Base Sepolia Testnet

Contract

0xc728AF6267315b5CB7669D7DC4F87f5174adabE8

Overview

ETH Balance

0 ETH

Token Holdings

More Info

Multichain Info

N/A
Transaction Hash
Method
Block
From
To
Amount
Create Position ...314159582025-09-23 4:03:2477 days ago1758600204IN
0xc728AF62...174adabE8
0 ETH0.000000410.00120018
Swap Token TWOTO...314159352025-09-23 4:02:3877 days ago1758600158IN
0xc728AF62...174adabE8
0 ETH0.000000210.00120018
Create Position ...314133752025-09-23 2:37:1877 days ago1758595038IN
0xc728AF62...174adabE8
0 ETH0.000000390.00120008
Create Position ...314131312025-09-23 2:29:1077 days ago1758594550IN
0xc728AF62...174adabE8
0 ETH0.000000390.00120009
Create Position ...314130112025-09-23 2:25:1077 days ago1758594310IN
0xc728AF62...174adabE8
0 ETH0.000000390.00120009
Create Position ...314128962025-09-23 2:21:2077 days ago1758594080IN
0xc728AF62...174adabE8
0 ETH0.000000410.00120009
Swap Token TWOTO...314128712025-09-23 2:20:3077 days ago1758594030IN
0xc728AF62...174adabE8
0 ETH0.000000190.00120009
Swap Token TWOTO...314128502025-09-23 2:19:4877 days ago1758593988IN
0xc728AF62...174adabE8
0 ETH0.000000210.00120008
Create Position ...313189982025-09-20 22:11:2480 days ago1758406284IN
0xc728AF62...174adabE8
0 ETH0.000000310.00091276
Create Position ...310939112025-09-15 17:08:3085 days ago1757956110IN
0xc728AF62...174adabE8
0 ETH0.000000340.00097006
Create Position ...310938542025-09-15 17:06:3685 days ago1757955996IN
0xc728AF62...174adabE8
0 ETH0.000000370.00097007
Swap Token TWOTO...310935752025-09-15 16:57:1885 days ago1757955438IN
0xc728AF62...174adabE8
0 ETH0.00000020.00097007
Create Position ...310551872025-09-14 19:37:4286 days ago1757878662IN
0xc728AF62...174adabE8
0 ETH0.000000350.00097012
Swap Token TWOTO...310550482025-09-14 19:33:0486 days ago1757878384IN
0xc728AF62...174adabE8
0 ETH0.000000150.00097
Swap Token TWOTO...310520542025-09-14 17:53:1686 days ago1757872396IN
0xc728AF62...174adabE8
0 ETH0.000000180.00097008
Create Position ...310177292025-09-13 22:49:0687 days ago1757803746IN
0xc728AF62...174adabE8
0 ETH0.000000370.00120009
Create Position ...309361672025-09-12 1:30:2288 days ago1757640622IN
0xc728AF62...174adabE8
0 ETH0.000000390.00120006
Swap Token TWOTO...308030782025-09-08 23:34:0492 days ago1757374444IN
0xc728AF62...174adabE8
0 ETH0.000000190.00120006
Swap Token TWOTO...308030102025-09-08 23:31:4892 days ago1757374308IN
0xc728AF62...174adabE8
0 ETH0.000000210.00120006
Create Position ...308025142025-09-08 23:15:1692 days ago1757373316IN
0xc728AF62...174adabE8
0 ETH0.000000370.00120006
Create Position ...305700652025-09-03 14:06:5897 days ago1756908418IN
0xc728AF62...174adabE8
0 ETH0.000000370.00120009
Create Position ...305693572025-09-03 13:43:2297 days ago1756907002IN
0xc728AF62...174adabE8
0 ETH0.000000370.00120008
Create Position ...305684212025-09-03 13:12:1097 days ago1756905130IN
0xc728AF62...174adabE8
0 ETH0.000000370.00120184
Create Position ...305679612025-09-03 12:56:5097 days ago1756904210IN
0xc728AF62...174adabE8
0 ETH0.000000370.00121078
Create Position ...305678052025-09-03 12:51:3897 days ago1756903898IN
0xc728AF62...174adabE8
0 ETH0.000000370.00121683
View all transactions

Parent Transaction Hash Block From To Amount
View All Internal Transactions

Loading...
Loading

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

Contract Name:
UniswapV4Swap

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 : Univ4MAKESWAP.sol
//Might want to change owner to cold storage address beofre mainnet although should never be used


// B ZERO X Token - Box Token Uniswap v4 Swap 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
//
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;


interface IPoolManager {
    /// @notice Struct containing data about liquidity modificationf
    struct ModifyLiquidityParams {
        // The lower tick of the position
        int24 tickLower;
        // The upper tick of the position
        int24 tickUpper;
        // The amount of liquidity to add or remove
        int256 liquidityDelta;

        bytes32 salt;
    }

    /// @notice Represents the balance changes of a transaction
    struct BalanceDelta {
        int128 amount0;
        int128 amount1;
    }

    /// @notice Struct containing pool key parameters
    struct PoolKey {
        // The first token of the pool, sorted by address
        Currency currency0;
        // The second token of the pool, sorted by address
        Currency currency1;
        // The fee tier of the pool
        uint24 fee;
        // The tickSpacing of the pool
        int24 tickSpacing;
        // The hooks of the pool
        address hooks;
    }

    /// @notice Modify the liquidity of a position in a pool
    /// @param key The pool key for the pool being modified
    /// @param params The parameters for modifying the position
    /// @param hookData Additional data to pass to the pool's hooks
    /// @return callerDelta The change in tokens owed to the caller
    /// @return feesAccrued The fees accrued as a result of the modification
    function modifyLiquidity(
        PoolKey memory key,
        ModifyLiquidityParams memory params,
        bytes calldata hookData
    ) external returns (BalanceDelta memory callerDelta, BalanceDelta memory feesAccrued);

    /// @notice Lock a pool for operations
    /// @param data Any data to pass along to the pool's hooks
    /// @return lockData Data to be passed to the pool's unlock function
    function lock(bytes calldata data) external returns (bytes memory lockData);

    /// @notice Unlock a pool after operations
    /// @param key The pool key for the pool being unlocked
    /// @param lockData Data returned from the lock function
    function unlock(PoolKey memory key, bytes memory lockData) external;
}
interface IUniswapV4Quoter {
    /**
     * @notice Struct containing parameters for quoting an exact input single swap
     * @param poolKey The pool key for the swap
     * @param zeroForOne Whether the swap is from token0 to token1 (true) or token1 to token0 (false)
     * @param amountIn The amount of input token to be swapped
     * @param sqrtPriceLimitX96 The price limit for the swap (0 for no limit)
     * @param hookData Additional data to be passed to the hook
     */


    struct QuoteExactSingleParams {
        PoolKey poolKey;
        bool zeroForOne;
        uint128 exactAmount;
        bytes hookData;
    }

    /**
     * @notice Quote an exact input single swap
     * @param params The parameters for the quote
     * @return amountOut The amount of output tokens that would be received
     * @return gasEstimate The estimated gas cost of the swap
     */
    function quoteExactInputSingle(QuoteExactSingleParams memory params)
        external
        returns (uint256 amountOut, uint256 gasEstimate);
}
// ============ Minimal Required Interfaces ============

interface IERC20 {
    function decimals() external view returns (uint8);
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
    function transfer(address recipient, uint256 amount) external returns (bool);
    function approve(address spender, uint256 amount) external returns (bool);
    function balanceOf(address account) external view returns (uint256);
}

// Define the Currency type as a wrapped address
type Currency is address;

// Provide global operator overloads for the Currency type
using {equals as ==} for Currency global;

// Define the equals operator
function equals(Currency currency, Currency other) pure returns (bool) {
    return Currency.unwrap(currency) == Currency.unwrap(other);
}

// Library with helper functions for Currency
library CurrencyLibrary {
    // A constant to represent native ETH (address zero)
    Currency public constant ADDRESS_ZERO = Currency.wrap(address(0));
    
    // Check if a Currency is the native currency (ETH)
    function isAddressZero(Currency currency) internal pure returns (bool) {
        return Currency.unwrap(currency) == address(0);
    }
}


/// @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;

// Minimal interface for Hooks
interface  IHooks{
    function beforeInitialize(address sender, PoolKey calldata key, uint160 sqrtPriceX96, bytes calldata hookData) external returns (bytes4);
    function afterInitialize(address sender, PoolKey calldata key, uint160 sqrtPriceX96, int24 tick, bytes calldata hookData) external returns (bytes4);
}

// Minimal representation of Uniswap V4 PoolKey
struct PoolKey {
    Currency currency0;
    Currency currency1;
    uint24 fee;
    int24 tickSpacing;
    IHooks hooks;
}


interface IPositionManager {

    function getPositionLiquidity(uint256 tokenId) external view returns (uint128 liquidity);


    
      /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipientsoperator
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be have been approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId) external;

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     * 
     * Requirements:
     * - Same as {safeTransferFrom}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     *
     * Additionally passes `data` to the destination contract. 
     */
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;

    function nextTokenId() external view returns (uint256);

        function getPoolAndPositionInfo(uint256 tokenId) external view returns (PoolKey memory poolKey, uint info);
    /**
     * @notice Modifies liquidities based on encoded actions in unlockData
     * @param unlockData Encoded data containing the actions to be executed
     * @param deadline Timestamp after which the transaction will revert
     * @dev Function is payable and includes isNotLocked and checkDeadline modifiers
     */
    function modifyLiquidities(
        bytes calldata unlockData,
        uint256 deadline
    ) external payable;
}


// Uniswap V4 Router interface (only what we need)
interface IV4Router {

    /**
     * @notice Executes commands with associated inputs validated against a deadline
     * @param commands A set of concatenated commands, each 1 byte in length
     * @param inputs The inputs associated with the commands
     * @param deadline The deadline by which the transaction must be executed
     * @dev Reverts if the current timestamp exceeds the deadline
     */
    function execute(
        bytes calldata commands,
        bytes[] calldata inputs,
        uint256 deadline
    ) external payable;


    struct ExactInputSingleParams {
        PoolKey poolKey;
        bool zeroForOne;
        uint128 amountIn;
        uint128 amountOutMinimum;
        bytes hookData;
    }
}



// WETH interface for wrapping/unwrapping ETH
interface IWETH is IERC20 {
    function deposit() external payable;
    function withdraw(uint256 amount) external;
}


/**
 * @title Uniswap V4 Swap Contract with ETH Support
 * @notice Implementation for swapping with Uniswap V4 pools with native ETH support
 */
 /**
 * @title IPermit2
 * @dev Interface for the Permit2 contract which handles token approvals with signatures
 */
interface IPermit2 {
    /**
     * @notice Approves the spender to use up to amount of the owner's token until the expiration timestamp
     * @param token The token address to approve
     * @param spender The address to approve for spending
     * @param amount The amount of tokens approved as a uint160
     * @param expiration The timestamp at which the approval expires (uint48)
     */
    function approve(
        address token,
        address spender,
        uint160 amount,
        uint48 expiration
    ) external;
}
//Recieve NFTs
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}
interface IStateView {
type PoolId is bytes32;

function getPositionInfo(PoolId poolId, address owner, int24 tickLower, int24 tickUpper, bytes32 salt)    external  view returns (uint128 liquidity, uint256 feeGrowthInside0LastX128, uint256 feeGrowthInside1LastX128);


    function getFeeGrowthInside(
        bytes32 poolId,
        int24 tickLower,
        int24 tickUpper
    ) external view returns (uint256 feeGrowthInside0X128, uint256 feeGrowthInside1X128);

    function getPositionInfo(
        PoolId poolId,
        bytes32 positionId
    ) external view returns (
        uint128 liquidity,
        uint256 feeGrowthInside0LastX128,
        uint256 feeGrowthInside1LastX128
    );

    /**
     * @notice Retrieves the Slot0 data for a specific pool
     * @param poolId The unique identifier of the pool
     * @return sqrtPriceX96 The current price of the pool as a sqrt(token1/token0) Q64.96 value
     * @return tick The current tick of the pool
     * @return protocolFee The current protocol fee setting of the pool
     * @return lpFee The current LP fee setting of the pool
     */
    function getSlot0(bytes32 poolId)
        external
        view
        returns (uint160 sqrtPriceX96, int24 tick, uint24 protocolFee, uint24 lpFee);
}


/// @notice Contract for executing swaps on Uniswap V4 on our B0x / 0xBitcoin liquidity pool
contract UniswapV4Swap {
   /// @notice Handles the receipt of an NFT
   /// @param operator The address which called `safeTransferFrom` function
   /// @param from The address which previously owned the token
   /// @param tokenId The NFT identifier which is being transferred
   /// @param data Additional data with no specified format
   /// @return bytes4 Returns the selector to confirm token transfer
   function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external pure returns (bytes4) {
       return IERC721Receiver.onERC721Received.selector;
   }
   
   /// @notice Minimum tick value for Uniswap V4 pools
   int24 private constant MIN_TICK = -887220;
   /// @notice Maximum tick value for Uniswap V4 pools
   int24 private constant MAX_TICK = 887220;
   
   /// @notice Event emitted when a new liquidity position is created
   /// @param tokenId The unique identifier of the created position NFT
   event PositionCreated(uint256 indexed tokenId);
   
   /// @notice Constant identifier for V4 swap operations
   uint256 constant V4_SWAP = 0x10;
   /// @notice Minimum sqrt ratio (corresponds to minimum price)
   uint160 constant MIN_SQRT_RATIO = 4295128739;
   /// @notice Maximum sqrt ratio (corresponds to maximum price)
   uint160 constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;
                                     
   /// @notice Interface for Uniswap V4 price quoter contract
   IUniswapV4Quoter public immutable quoter = IUniswapV4Quoter(0x4A6513c898fe1B2d0E78d3b0e0A4a151589B1cBa);
   /// @notice Interface for viewing pool state information
   IStateView public immutable stateView = IStateView(0x571291b572ed32ce6751a2Cb2486EbEe8DEfB9B4);
   /// @notice Interface for managing liquidity positions
   IPositionManager public immutable positionManager = IPositionManager(0x4B2C77d209D3405F41a037Ec6c77F7F5b8e2ca80);
   /// @notice The Uniswap V4 pool manager contract
   IPoolManager public immutable poolManager = IPoolManager(0x05E73354cFDd6745C338b50BcFDfA3Aa6fA03408);
   /// @notice Interface for Uniswap V4 router contract
   IV4Router public immutable IV4UniswapRouter= IV4Router(0x492E6456D9528771018DeB9E87ef7750EF184104);
   /// @notice Interface for Wrapped Ether (WETH) contract
   IWETH public immutable WETH = IWETH(0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14);
   /// @notice Address of the Permit2 contract for token approvals
   address public permit2 = address(0x000000000022D473030F116dDEE9F6B43aC78BA3);
   
   /// @notice Event emitted when a swap is executed
   /// @param tokenIn The address of the input token
   /// @param tokenOut The address of the output token
   /// @param amountIn The amount of input tokens
   /// @param amountOut The amount of output tokens received
   /// @param sender The address that initiated the swap
   event SwapExecuted(
       address indexed tokenIn,
       address indexed tokenOut,
       uint256 amountIn,
       uint256 amountOut,
       address indexed sender
   );
   
   /// @notice Address of the contract owner
   address owner;
   
   /// @notice Modifier to restrict access to owner only
   modifier onlyOwner() 
   {
       require(msg.sender == owner,"Only Owner");
       _;
   }
   
   /// @notice Constructor to initialize the contract sets owner as msg.sender
   constructor()
   {
       /// @notice Set the deployer as the contract owner
       owner =  msg.sender;
   }

   /// @notice Withdraws an NFT position from the contract to the owner
   /// @param tokenID The unique identifier of the NFT position to withdraw
   /// @return bool Returns true if withdrawal is successful
   function withdrawNFT (uint tokenID) public onlyOwner returns (bool){
       positionManager.approve(address(this), tokenID);
       positionManager.safeTransferFrom(address(this), owner, tokenID);
       
   }

   /// @notice Withdraws all tokens of a specific type from the contract to the owner
   /// @param token The address of the token contract to withdraw
   /// @return bool Returns true if withdrawal is successful
   function withdrawTokens (address token) public onlyOwner returns (bool){
       /// @notice Current balance of the specified token in this contract
       uint balancezzz = IERC20(token).balanceOf(address(this));
       IERC20(token).transfer(owner, balancezzz);
       return true;
   }

   /// @notice Withdraws all ETH from the contract to the owner
   /// @return bool Returns true if withdrawal is successful
   function withdrawETH() public onlyOwner returns (bool) {
       /// @notice Current ETH balance of this contract
       uint256 balance = address(this).balance;
       /// @notice Success status of the ETH transfer
       (bool success,) = payable(owner).call{value: balance}("");
       require(success, "Transfer failed");
       return true;
   }

 
   /// @notice Converts a PoolKey struct to a unique pool identifier
   /// @param poolKey The pool key structure containing pool parameters
   /// @return poolId The unique bytes32 identifier for the pool
   function toId(PoolKey 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 Performs a swap from token to ETH with correct parameter encoding
    * @param tokenA First token address for pool identification
    * @param tokenB Second token address for pool identification
    * @param tokenIn Input token address
    * @param tokenOut Output token address
    * @param amountIn Amount of input token
    * @param minAmountOut Minimum output amount
    * @param hookAddress Hook address for the pool
    * @param WhereToSendFunds Address to receive the swapped tokens
    * @return bool Returns true if swap is successful
    */
   function swapTokenTWOTOKENS(
       address tokenA,
       address tokenB,
       address tokenIn,
       address tokenOut,
       uint256 amountIn,
       uint256 minAmountOut,
       address hookAddress,
       address WhereToSendFunds
   ) external returns (bool) 
   {
       /// @notice Sorted token addresses (token0 must be < token1)
       (address token0, address token1) = tokenA < tokenB
           ? (tokenA, tokenB)
           : (tokenB, tokenA);
       
       IERC20(tokenIn).approve(address(permit2), type(uint256).max);
       IPermit2(permit2).approve(tokenIn, address(IV4UniswapRouter), type(uint160).max, uint48(block.timestamp)+60*60*1);
       
       // Transfer tokens from sender
       IERC20(tokenIn).transferFrom(msg.sender, address(this), amountIn);
       
       // Command for V4_SWAP
       /// @notice Command bytes for V4 swap operation
       bytes memory commands = new bytes(1);
       commands = abi.encodePacked(uint8(0x10));
       
       // Actions
       /// @notice Action sequence for the swap operation
       bytes memory actions = new bytes(3);
       actions[0] = bytes1(0x06); // SWAP_EXACT_IN_SINGLE
       actions[1] = bytes1(0x0c); // SETTLE_ALL
       actions[2] = bytes1(0x0f); // TAKE_ALL
       //actions[3] = bytes1(0x16); // UNWRAP
       
       // Create pool key
       /// @notice Pool key structure containing all pool parameters
       PoolKey memory poolKey = PoolKey({
           currency0: Currency.wrap(token0),
           currency1: Currency.wrap(token1), // ETH
           fee: 0x800000,
           tickSpacing: 60,
           hooks: IHooks(hookAddress)
       });
       
       // Ensure tokens are ordered properly
       // Determine swap direction based on token addresses
       
       // 1. FIX: Calculate zeroForOne correctly (don't hardcode as true)
       /// @notice Direction of the swap (true if swapping token0 for token1)
       bool zeroForOne = tokenIn == token0; // This determines swap direction
       // 2. FIX: SWAP_EXACT_IN_SINGLE parameter encoding - use the proper struct
       /// @notice Encoded parameters for the swap operation
       bytes memory swapParams = abi.encode(
           IV4Router.ExactInputSingleParams({
               poolKey: poolKey,
               zeroForOne: zeroForOne,  // Use calculated value, not hardcoded true
               amountIn: uint128(amountIn),
               amountOutMinimum: uint128(minAmountOut),
               hookData: bytes("")
           })
       );
       // 3. FIX: SETTLE_ALL parameters - should be (currency, amount)
       /// @notice Input currency for settlement
       Currency inputCurrency = zeroForOne ? poolKey.currency0 : poolKey.currency1;
       /// @notice Encoded parameters for settling input currency
       bytes memory settleAllParams = abi.encode(inputCurrency, amountIn);
       // 4. FIX: TAKE_ALL parameters - should be (currency, minAmount) 
       /// @notice Output currency to take
       Currency outputCurrency = zeroForOne ? poolKey.currency1 : poolKey.currency0;
       /// @notice Encoded parameters for taking output currency
       bytes memory takeAllParams = abi.encode(outputCurrency, minAmountOut);
       
       // Combine all params
       /// @notice Array of all encoded parameters for the swap actions
       bytes[] memory allParams = new bytes[](3);
       allParams[0] = swapParams;
       allParams[1] = settleAllParams;
       allParams[2] = takeAllParams;
       
       // Encode all actions and params
       /// @notice Input data for router execution
       bytes[] memory inputs = new bytes[](1);
       inputs[0] = abi.encode(actions, allParams);
       
       // Execute the swap
       /// @notice Deadline for the swap transaction
       uint256 deadline = block.timestamp + 60;
       IV4UniswapRouter.execute(commands, inputs, deadline);
       /// @notice Remaining balance of input token in contract
       uint tokenInValue = IERC20(tokenIn).balanceOf(address(this));
       /// @notice Balance of output token in contract
       uint tokenOutValue = IERC20(tokenOut).balanceOf(address(this));
       if(tokenInValue >0){
           IERC20(tokenIn).transfer(WhereToSendFunds, tokenInValue);
       }
       if(tokenOutValue >0)
       {
           IERC20(tokenOut).transfer(WhereToSendFunds, tokenOutValue);
       }
       return true;
   }

   /// @notice Gets the pool key for a token pair with specified hook
   /// @param tokenA First token address in the pair
   /// @param tokenB Second token address in the pair
   /// @param hookAddress Address of the hook contract for the pool
   /// @return PoolKey memory structure containing pool parameters
   function getPoolKey(address tokenA, address tokenB, address hookAddress) public view returns (PoolKey memory)
   {
       // Determine correct token ordering for the pool
       /// @notice Sorted token addresses (token0 must be < token1)
       (address token0, address token1) = tokenA < tokenB
           ? (tokenA, tokenB)
           : (tokenB, tokenA);
       
       // Create pool key with properly ordered tokens
       /// @notice Pool key structure with ordered tokens and parameters
       PoolKey memory poolKey = PoolKey({
           currency0: Currency.wrap(token0),
           currency1: Currency.wrap(token1),
           fee: 0x800000,
           tickSpacing: 60,
           hooks: IHooks(hookAddress)
       });
       
       return poolKey;
   }
   
   
   /// @notice Gets the expected output amount for a token swap
   /// @param tokenZeroxBTC Address of the 0xBTC token
   /// @param tokenBZeroX Address of the BZeroX token
   /// @param tokenIn Address of the input token
   /// @param hookAddress Address of the hook contract
   /// @param amountIn Amount of input tokens
   /// @return amountOut Expected amount of output tokens
   function getOutput(address tokenZeroxBTC, address tokenBZeroX, address tokenIn, address hookAddress, uint128 amountIn) public returns (uint amountOut)
   {
       /// @notice Pool key for the token pair
       PoolKey memory keyz = getPoolKey(tokenZeroxBTC, tokenBZeroX, hookAddress);
       
       // Determine swap direction based on token addresses
       /// @notice Direction of swap (true if swapping token0 for token1)
       bool zeroForOne = tokenIn == Currency.unwrap(keyz.currency0);
       
       // Create the QuoteExactSingleParams structure
       /// @notice Parameters for exact input quote calculation
       IUniswapV4Quoter.QuoteExactSingleParams memory params = IUniswapV4Quoter.QuoteExactSingleParams({
           poolKey: keyz,
           zeroForOne: zeroForOne,
           exactAmount: amountIn,
           hookData: bytes("") // Empty bytes for no hook data
       });
       
       // Call the quoter and get the amount out
       /// @notice Quote result with amount out and additional data
       (amountOut, ) = quoter.quoteExactInputSingle(params);
       return amountOut;
   }
   

    /// @notice A helper function to calculate the position key
    /// @param owner2 The address of the position owner
    /// @param tickLower the lower tick boundary of the position
    /// @param tickUpper the upper tick boundary of the position
    /// @param salt A unique value to differentiate between multiple positions in the same range, by the same owner. Passed in by the caller.
    function calculatePositionKey(address owner2, int24 tickLower, int24 tickUpper, bytes32 salt) internal pure returns (bytes32 positionKey)
    {
         //positionKey = keccak256(abi.encodePacked(owner2, tickLower, tickUpper, salt));
          assembly ("memory-safe") {
            let fmp := mload(0x40)
            mstore(add(fmp, 0x26), salt) // [0x26, 0x46)
            mstore(add(fmp, 0x06), tickUpper) // [0x23, 0x26)
            mstore(add(fmp, 0x03), tickLower) // [0x20, 0x23)
            mstore(fmp, owner2) // [0x0c, 0x20)
            positionKey := keccak256(add(fmp, 0x0c), 0x3a) // len is 58 bytes

            // now clean the memory we used
            mstore(add(fmp, 0x40), 0) // fmp+0x40 held salt
            mstore(add(fmp, 0x20), 0) // fmp+0x20 held tickLower, tickUpper, salt
            mstore(fmp, 0) // fmp held owner
        }
    }


    /// @notice Represents the balance changes of a transaction
    struct BalanceDelta {
        int128 amount0;
        int128 amount1;
    }
    
/* example if u need help increase or decrease
   /// @notice Increases liquidity for an existing position with two tokens
   /// @param tokenA Address of the first token
   /// @param tokenB Address of the second token
   /// @param hookAddress Address of the hook contract for the pool
   /// @param amountA Amount of tokenA to add
   /// @param amountB Amount of tokenB to add
   /// @param tokenID ID of the existing position to increase liquidity for
   /// @param fees0 Amount of fees for token0 to use from position
   /// @param fees1 Amount of fees for token1 to use from position
   /// @return bool Returns true if liquidity increase is successful
   function increaseLiqTwoTokens(address tokenA, address tokenB, address hookAddress, uint amountA, uint amountB, uint tokenID, uint fees0, uint fees1) public payable returns (bool)
   {
      
      //modifyLiquidity
      
      /// @notice Sorted token addresses (token0 must be < token1)
      (address token0, address token1) = tokenA < tokenB
         ? (tokenA, tokenB)
         : (tokenB, tokenA);
      
      /// @notice Sorted token amounts based on token ordering
      (uint256 amount0, uint256 amount1) = tokenA < tokenB
         ? (amountA, amountB)
         : (amountB, amountA);
      
      /// @notice Sorted fee amounts based on token ordering
      (uint fees0a, uint fees1a) = tokenA < tokenB
         ? (fees0, fees1)
         : (fees1, fees0);

      /// @notice Approve permit2 for maximum allowance
      IERC20(token0).approve(address(permit2), type(uint256).max);
      IERC20(token1).approve(address(permit2), type(uint256).max);
      IPermit2(permit2).approve(token0, address(positionManager), type(uint160).max, uint48(block.timestamp)+60*60*1);
      IPermit2(permit2).approve(token1, address(positionManager), type(uint160).max, uint48(block.timestamp)+60*60*1);
      
      // Transfer tokens from sender only if amount > fees
      if(amount0 > fees0a) {
         IERC20(token0).transferFrom(msg.sender, address(this), amount0-fees0a);
      }

      if(amount1 > fees1a) {
         IERC20(token1).transferFrom(msg.sender, address(this), amount1-fees1a);
      }

      /// @notice Pool key structure for the token pair
      PoolKey memory poolKey = PoolKey(Currency.wrap(address(token0)), Currency.wrap(token1), 0x800000, 60, IHooks(hookAddress));
      /// @notice Pool ID derived from pool key
      bytes32 idz = toId(poolKey);
      
      /// @notice Current sqrt price from pool state
      (uint160 sqrtPricex96,,,) = stateView.getSlot0(idz);
      // Convert ticks to sqrtPriceX96 values
      // Convert specific ticks to sqrtPriceX96 values
      /// @notice Lower tick for full range position
      int24 tickLower = -887220; // Your desired lower tick
      /// @notice Upper tick for full range position
      int24 tickUpper = 887220;  // Your desired upper tick

      // Convert ticks to sqrtPriceX96 values
      /// @notice Sqrt ratio at lower tick
      uint160 sqrtRatioAX96 = getSqrtRatioAtTick(tickLower);
      /// @notice Sqrt ratio at upper tick
      uint160 sqrtRatioBX96 = getSqrtRatioAtTick(tickUpper);

      /// @notice Calculated liquidity delta for the given amounts
      uint liquidityDelta = getLiquidityForAmounts(
         sqrtPricex96,
         sqrtRatioAX96,
         sqrtRatioBX96,
         amount0,
         amount1
      );
      
      
      /// @notice Parameters for position manager actions
      bytes[] memory params = new bytes[](2); // new bytes[](3) for ETH liquidity positions

      params[0] = abi.encode(tokenID, liquidityDelta, amount0, amount1, bytes(""));

      /// @notice Currency wrapper for token0
      Currency currency0 = Currency.wrap(token0); // tokenAddress1 = 0 for native ETH
      /// @notice Currency wrapper for token1
      Currency currency1 = Currency.wrap(token1);

      params[1] = abi.encode(currency0, currency1); //settle pair
      /// @notice Actions to perform: increase liquidity and settle pair
      bytes memory actions = abi.encodePacked(uint8(0x00), uint8(0x0d));
      // Cap remaining fees to avoid claiming more than available
      /// @notice Remaining fees for token0 after liquidity increase
      uint256 remainingFees0 = fees0a > amount0 ? fees0a - amount0 : 0;
      /// @notice Remaining fees for token1 after liquidity increase
      uint256 remainingFees1 = fees1a > amount1 ? fees1a - amount1 : 0;

      // Only use TAKE_PAIR if there are actually remaining fees to claim
      if((remainingFees0 > 0 || remainingFees1 > 0)){
         params = new bytes[](3); 
         //need to take pair not settle pair
         /// @notice Updated actions for closing currencies when fees remain
         actions = abi.encodePacked(
            uint8(0x00),  // INCREASE_LIQUIDITY
            uint8(0x12),  // CLOSE_CURRENCY
            uint8(0x12)   // CLOSE_CURRENCY
         );
         params[0] = abi.encode(tokenID, liquidityDelta, amount0, amount1, bytes(""));
         params[1] = abi.encode(Currency.wrap(token0));  // Close token0
         params[2] = abi.encode(Currency.wrap(token1));  // Close token1
      }

      /// @notice Transaction deadline
      uint256 deadline = block.timestamp + 160;

      /// @notice ETH value to pass to position manager
      uint256 valueToPass = msg.value;

      positionManager.modifyLiquidities{value: valueToPass}(
         abi.encode(actions, params),
         deadline
      );

      /// @notice Return any remaining token0 balance to sender
      uint token0Balance = IERC20(token0).balanceOf(address(this));
      /// @notice Return any remaining token1 balance to sender
      uint token1Balance = IERC20(token1).balanceOf(address(this));
      if(token0Balance>0){
         IERC20(token0).transfer(msg.sender, token0Balance);
      }
      if(token1Balance>0){
         IERC20(token1).transfer(msg.sender, token1Balance);
      }
      //  emit PositionCreated(nextID);
      return true;
   }
   
   
   /// @notice Decreases liquidity from an existing position by a specified percentage
   /// @param percentagedivby10000 Percentage to remove divided by 10000 (e.g., 2500 = 25%)
   /// @param tokenA Address of the first token in the pair
   /// @param tokenB Address of the second token in the pair
   /// @param hookAddress Address of the hook contract for the pool
   /// @param amount0_min Minimum amount of token0 to receive
   /// @param amount1_min Minimum amount of token1 to receive
   /// @param tokenID ID of the position to decrease liquidity from
   /// @return bool Returns true if liquidity decrease is successful
   function decreaseLiqTwoTokens(uint percentagedivby10000, address tokenA, address tokenB, address hookAddress, uint256 amount0_min, uint amount1_min, uint tokenID) public returns (bool){
      // Check if NFT is full-range
      /// @notice Current liquidity amount in the position
      ( uint128 liquidity ) = 
         positionManager.getPositionLiquidity(tokenID);
      /// @notice Amount of liquidity to remove based on percentage
      uint liqtoRemove = liquidity * percentagedivby10000 / 10000;

      //modifyLiquidity
      /// @notice Sorted token addresses (token0 must be < token1)
      (address token0, address token1) = tokenA < tokenB
         ? (tokenA, tokenB)
         : (tokenB, tokenA);
      
      /// @notice Sorted minimum amounts based on token ordering
      (uint amountA_min, uint amountB_min) = tokenA < tokenB
         ? (amount0_min, amount1_min)
         : (amount1_min, amount0_min);

      //bytes memory actions = abi.encodePacked(uint8(Actions.DECREASE_LIQUIDITY), uint8(Actions.TAKE_PAIR));
      //DECREASE_LIQUIDITY = 0x01,
      // TAKE_PAIR = 0x11,
      /// @notice Actions to perform: decrease liquidity and take pair
      bytes memory actions = abi.encodePacked(uint8(0x01), uint8(0x11));
      /// @notice Parameters for position manager actions
      bytes[] memory params = new bytes[](2); //for take pair
      //bytes[] memory params = new bytes[](3); // new bytes[](3) for ETH liquidity positions
      params[0] = abi.encode(tokenID, liqtoRemove, amountA_min, amountB_min, bytes(""));
      /// @notice Currency wrapper for token0
      Currency currency0 = Currency.wrap(token0); // tokenAddress1 = 0 for native ETH
      /// @notice Currency wrapper for token1
      Currency currency1 = Currency.wrap(token1);
      params[1] = abi.encode(currency0, currency1, msg.sender); //take pair
      //For ETH see 2 tokens @ https://docs.uniswap.org/contracts/v4/quickstart/manage-liquidity/increase-liquidity
      //_toCurrency params[2] = abi.encode(currency0, address(this)); //sweep
      /// @notice Transaction deadline
      uint256 deadline = block.timestamp + 160;



      positionManager.modifyLiquidities{value: 0}(
         abi.encode(actions, params),
         deadline
      );
      //  emit PositionCreated(nextID);
      return true;
   }

   */
   
  
    /// @notice Calculates floor(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
    /// @param a The multiplicand
    /// @param b The multiplier
    /// @param denominator The divisor
    /// @return result The 256-bit result
    /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv
    function mulDiv(uint256 a, uint256 b, uint256 denominator) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = a * b
            // Compute the product mod 2**256 and mod 2**256 - 1
            // then use the Chinese Remainder Theorem to reconstruct
            // the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2**256 + prod0
            uint256 prod0 = a * b; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly ("memory-safe") {
                let mm := mulmod(a, b, not(0))
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Make sure the result is less than 2**256.
            // Also prevents denominator == 0
            require(denominator > prod1);

            // Handle non-overflow cases, 256 by 256 division
            if (prod1 == 0) {
                assembly ("memory-safe") {
                    result := div(prod0, denominator)
                }
                return result;
            }

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0]
            // Compute remainder using mulmod
            uint256 remainder;
            assembly ("memory-safe") {
                remainder := mulmod(a, b, denominator)
            }
            // Subtract 256 bit number from 512 bit number
            assembly ("memory-safe") {
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator
            // Compute largest power of two divisor of denominator.
            // Always >= 1.
            uint256 twos = (0 - denominator) & denominator;
            // Divide denominator by power of two
            assembly ("memory-safe") {
                denominator := div(denominator, twos)
            }

            // Divide [prod1 prod0] by the factors of two
            assembly ("memory-safe") {
                prod0 := div(prod0, twos)
            }
            // Shift in bits from prod1 into prod0. For this we need
            // to flip `twos` such that it is 2**256 / twos.
            // If twos is zero, then it becomes one
            assembly ("memory-safe") {
                twos := add(div(sub(0, twos), twos), 1)
            }
            prod0 |= prod1 * twos;

            // Invert denominator mod 2**256
            // Now that denominator is an odd number, it has an inverse
            // modulo 2**256 such that denominator * inv = 1 mod 2**256.
            // Compute the inverse by starting with a seed that is correct
            // correct for four bits. That is, denominator * inv = 1 mod 2**4
            uint256 inv = (3 * denominator) ^ 2;
            // Now use Newton-Raphson iteration to improve the precision.
            // Thanks to Hensel's lifting lemma, this also works in modular
            // arithmetic, doubling the correct bits in each step.
            inv *= 2 - denominator * inv; // inverse mod 2**8
            inv *= 2 - denominator * inv; // inverse mod 2**16
            inv *= 2 - denominator * inv; // inverse mod 2**32
            inv *= 2 - denominator * inv; // inverse mod 2**64
            inv *= 2 - denominator * inv; // inverse mod 2**128
            inv *= 2 - denominator * inv; // inverse mod 2**256

            // Because the division is now exact we can divide by multiplying
            // with the modular inverse of denominator. This will give us the
            // correct result modulo 2**256. Since the preconditions guarantee
            // that the outcome is less than 2**256, this is the final result.
            // We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inv;
            return result;
        }
    }
    uint256 constant Q96 = 0x1000000000000000000000000;


    error SafeCastOverflow();

    /// @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) revert("under 0");
        y = uint128(x);
    }

    /// @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) revert("not equal");
    }


    /// @notice Computes the amount of liquidity received for a given amount of token0 and price range
    /// @dev Calculates amount0 * (sqrt(upper) * sqrt(lower)) / (sqrt(upper) - sqrt(lower))
    /// @param sqrtPriceAX96 A sqrt price representing the first tick boundary
    /// @param sqrtPriceBX96 A sqrt price representing the second tick boundary
    /// @param amount0 The amount0 being sent in
    /// @return liquidity The amount of returned liquidity
    function getLiquidityForAmount0(uint160 sqrtPriceAX96, uint160 sqrtPriceBX96, uint256 amount0) internal pure returns (uint128 liquidity)
    {
        unchecked {
            if (sqrtPriceAX96 > sqrtPriceBX96) (sqrtPriceAX96, sqrtPriceBX96) = (sqrtPriceBX96, sqrtPriceAX96);
            uint256 intermediate = mulDiv(sqrtPriceAX96, sqrtPriceBX96, Q96);
            return toUint128(mulDiv(amount0, intermediate, sqrtPriceBX96 - sqrtPriceAX96));
        }
    }


    /// @notice Computes the amount of liquidity received for a given amount of token1 and price range
    /// @dev Calculates amount1 / (sqrt(upper) - sqrt(lower)).
    /// @param sqrtPriceAX96 A sqrt price representing the first tick boundary
    /// @param sqrtPriceBX96 A sqrt price representing the second tick boundary
    /// @param amount1 The amount1 being sent in
    /// @return liquidity The amount of returned liquidity
    function getLiquidityForAmount1(uint160 sqrtPriceAX96, uint160 sqrtPriceBX96, uint256 amount1) internal pure returns (uint128 liquidity)
    {
        unchecked {
            if (sqrtPriceAX96 > sqrtPriceBX96) (sqrtPriceAX96, sqrtPriceBX96) = (sqrtPriceBX96, sqrtPriceAX96);
            return toUint128(mulDiv(amount1, Q96, sqrtPriceBX96 - sqrtPriceAX96));
        }
    }


    /// @notice Computes the maximum amount of liquidity received for a given amount of token0, token1, the current
    /// pool prices and the prices at the tick boundaries
    /// @param sqrtPriceX96 A sqrt price representing the current pool prices
    /// @param sqrtPriceAX96 A sqrt price representing the first tick boundary
    /// @param sqrtPriceBX96 A sqrt price representing the second tick boundary
    /// @param amount0 The amount of token0 being sent in
    /// @param amount1 The amount of token1 being sent in
    /// @return liquidity The maximum amount of liquidity received
    function getLiquidityForAmounts(uint160 sqrtPriceX96, uint160 sqrtPriceAX96, uint160 sqrtPriceBX96, uint256 amount0, uint256 amount1) public pure returns (uint128 liquidity)
    {
        if (sqrtPriceAX96 > sqrtPriceBX96) (sqrtPriceAX96, sqrtPriceBX96) = (sqrtPriceBX96, sqrtPriceAX96);

        if (sqrtPriceX96 <= sqrtPriceAX96) {
            liquidity = getLiquidityForAmount0(sqrtPriceAX96, sqrtPriceBX96, amount0);
        } else if (sqrtPriceX96 < sqrtPriceBX96) {
            uint128 liquidity0 = getLiquidityForAmount0(sqrtPriceX96, sqrtPriceBX96, amount0);
            uint128 liquidity1 = getLiquidityForAmount1(sqrtPriceAX96, sqrtPriceX96, amount1);

            liquidity = liquidity0 < liquidity1 ? liquidity0 : liquidity1;
        } else {
            liquidity = getLiquidityForAmount1(sqrtPriceAX96, sqrtPriceBX96, amount1);
        }
    }

   /// @notice Returns the next available token ID from the position manager
   /// @return uint256 The next token ID that will be minted
   function nextIDis() public view returns (uint256){
      return positionManager.nextTokenId();
   }

   /// @notice Calculates the price ratio from sqrtPriceX96 with specified decimal precision
   /// @dev Clean implementation using MulDiv for overflow-safe calculations
   /// @param sqrtPriceX96 The sqrt price in X96 format from Uniswap V4
   /// @param decimals Number of decimal places for the returned price ratio
   /// @return priceRatio The price ratio scaled by 10^decimals
   function getPriceRatioWithDecimals(uint160 sqrtPriceX96, uint8 decimals) public pure returns (uint256 priceRatio) {
      if (sqrtPriceX96 == 0) return 0;
      
      /// @notice Convert sqrtPriceX96 to uint256 for calculations
      uint256 sqrtPrice = uint256(sqrtPriceX96);
      /// @notice Decimal multiplier for final price scaling
      uint256 multiplier = 10 ** decimals;
      
      // Calculate price = (sqrtPriceX96^2 * 10^decimals) / 2^192
      // Using MulDiv for safe high-precision arithmetic
      
      // First: sqrtPrice^2
      /// @notice Price in X192 format (sqrtPrice squared)
      uint256 priceX192 = sqrtPrice * sqrtPrice; // This is safe with your corrected values
      
      // Second: MulDiv(priceX192, multiplier, 2^192)
      /// @notice Q192 constant representing 2^192 for price conversion
      uint256 Q192 = 1 << 192;
      /// @notice Final price ratio calculation using safe math
      priceRatio = mulDiv(priceX192, multiplier, Q192);
      
      return priceRatio;
   }


   /// @notice Gets the price ratio and token information for a token pair
   /// @param token Address of the first token
   /// @param token2 Address of the second token
   /// @param hookAddress Address of the hook contract for the pool
   /// @return ratio Price ratio scaled to 18 decimals
   /// @return token0z Address of token0 (lower address)
   /// @return token1z Address of token1 (higher address)
   /// @return token0decimals Decimal places of token0
   /// @return token1decimals Decimal places of token1
   function getPriceRatio(address token, address token2, address hookAddress) public view returns (uint ratio, address token0z, address token1z, uint8 token0decimals, uint8 token1decimals) {
      
      // Determine correct token ordering for the pool
      /// @notice Sorted token addresses (token0 must be < token1)
      (address token0, address token1) = token < token2
         ? (token, token2)
         : (token2, token);
      
      /// @notice Pool key structure for the token pair
      PoolKey memory poolKey = PoolKey(Currency.wrap(token0), Currency.wrap(token1), 0x800000, 60, IHooks(hookAddress));
      /// @notice Pool ID derived from pool key
      bytes32 idz = toId(poolKey);
      
      /// @notice Current sqrt price from pool state
      (uint160 sqrtPricex96,,,) = stateView.getSlot0(idz);
      /// @notice Price ratio scaled to 18 decimal places
      uint priceRatiox18decimals2 = getPriceRatioWithDecimals(sqrtPricex96, 18);
      /// @notice Decimal places of token0
      token0decimals = IERC20(token0).decimals();
      /// @notice Decimal places of token1
      token1decimals = IERC20(token1).decimals();
      token0z=token0;
      token1z=token1;
      return (priceRatiox18decimals2, token0, token1, token0decimals, token1decimals);
   }
   
   
   /// @notice Gets the current sqrt price in X96 format for a token pair
   /// @param token Address of the first token
   /// @param token2 Address of the second token
   /// @param hookAddress Address of the hook contract for the pool
   /// @return uint160 The sqrt price in X96 format
   function getsqrtPricex96(address token, address token2, address hookAddress)public view returns(uint160)
   {
      // Determine correct token ordering for the pool
      /// @notice Sorted token addresses (token0 must be < token1)
      (address token0, address token1) = token < token2
         ? (token, token2)
         : (token2, token);
      // Create PoolKey with correctly ordered tokens
      /// @notice Pool key structure with ordered tokens and parameters
      PoolKey memory poolKey = PoolKey(
         Currency.wrap(token0), 
         Currency.wrap(token1), 
         0x800000, 
         60, 
         IHooks(hookAddress)
      );
      
      /// @notice Pool ID derived from pool key
      bytes32 idz = toId(poolKey);
      
      /// @notice Current sqrt price from pool state in X96 format
      (uint160 sqrtPricex96,,,) = stateView.getSlot0(idz);
      return sqrtPricex96;
   }


   /// @notice Creates a new liquidity position with two tokens
   /// @param token Address of the first token
   /// @param token2 Address of the second token
   /// @param amountIn Amount of first token to deposit
   /// @param amountIn2 Amount of second token to deposit
   /// @param currentx96 Expected sqrtPriceX96 when user initiated transaction
   /// @param slippage Slippage tolerance in basis points (e.g., 100 = 1%)
   /// @param hookAddress Address of the hook contract for the pool
   /// @param toSendNFTto Address to receive the NFT representing the position
   /// @return bool Returns true if position creation is successful
   function createPositionWith2Tokens(address token, address token2, uint256 amountIn, uint256 amountIn2, uint currentx96, uint256 slippage, address hookAddress, address toSendNFTto) public payable returns (bool)
   {

      // Determine correct token ordering for the pool
      /// @notice Sorted token addresses (token0 must be < token1)
      (address token0, address token1) = token < token2
         ? (token, token2)
         : (token2, token);
      
      // Reorder amounts to match token ordering
      /// @notice Sorted token amounts based on token ordering
      (uint256 amount0, uint256 amount1) = token < token2
         ? (amountIn, amountIn2)
         : (amountIn2, amountIn);

      /*     For when using two tokens do this
         (address token0, address token1) = tokenA < tokenB
               ? (tokenA, tokenB)
               : (tokenB, tokenA);
         
         (amountA, amountB) = tokenA < tokenB
               ? (amountA, amountB)
               : (amountB, amountA);
         */

      // Transfer tokens from sender
      IERC20(token0).transferFrom(msg.sender, address(this), amount0);
      
      // Transfer tokens from sender
      IERC20(token1).transferFrom(msg.sender, address(this), amount1);
      

      // Step 1: Your contract approves Permit2 to spend the tokens (standard ERC20 approve)
      IERC20(token0).approve(permit2, amount0);
      IERC20(token1).approve(permit2, amount1);

      IPermit2(permit2).approve(token0, address(positionManager), type(uint160).max, uint48(block.timestamp)+60*60*1);
      IPermit2(permit2).approve(token1, address(positionManager), type(uint160).max, uint48(block.timestamp)+60*60*1);
      
      // Create PoolKey with correctly ordered tokens
      /// @notice Pool key structure with ordered tokens and parameters
      PoolKey memory poolKey = PoolKey(
         Currency.wrap(token0), 
         Currency.wrap(token1), 
         0x800000, 
         60, 
         IHooks(hookAddress)
      );
      
      /// @notice Pool ID derived from pool key
      bytes32 idz = toId(poolKey);
      
      /// @notice Current sqrt price from pool state
      (uint160 sqrtPricex96,,,) = stateView.getSlot0(idz);

      // SLIPPAGE PROTECTION: Check if price has moved too much
      /// @notice Maximum allowed slippage in basis points
      uint256 maxSlippageBps = slippage; // e.g., 100 = 1%, 500 = 5%
      /// @notice Expected price when transaction was initiated
      uint256 expectedPrice = uint256(currentx96);
      /// @notice Current actual price from the pool
      uint256 actualPrice = uint256(sqrtPricex96);
      
      // Calculate acceptable price range
      /// @notice Minimum acceptable price considering slippage
      uint256 minAcceptablePrice = (expectedPrice * (10000 - maxSlippageBps)) / 10000;
      /// @notice Maximum acceptable price considering slippage
      uint256 maxAcceptablePrice = (expectedPrice * (10000 + maxSlippageBps)) / 10000;
      
      require(
         actualPrice >= minAcceptablePrice && actualPrice <= maxAcceptablePrice,
         "Price moved beyond slippage tolerance"
      );

      // Convert ticks to sqrtPriceX96 values
      // Convert specific ticks to sqrtPriceX96 values
      /// @notice Lower tick for full range position
      int24 tickLower = -887220; // Your desired lower tick
      /// @notice Upper tick for full range position
      int24 tickUpper = 887220;  // Your desired upper tick

      // Convert ticks to sqrtPriceX96 values
      /// @notice Sqrt ratio at lower tick
      uint160 sqrtRatioAX96 = getSqrtRatioAtTick(tickLower);
      /// @notice Sqrt ratio at upper tick
      uint160 sqrtRatioBX96 = getSqrtRatioAtTick(tickUpper);

      /// @notice Calculated liquidity delta for the given amounts
      uint liquidityDelta = getLiquidityForAmounts(
         sqrtPricex96,
         sqrtRatioAX96,
         sqrtRatioBX96,
         amount0,
         amount1
      );
   
      // For ETH liquidity positions
         
      // Actions
      // MINT_POSITION = 0x02,
      // SETTLE_PAIR = 0x0d,
      //SWEEP = 0x14,
      /// @notice Actions to perform: mint position and settle pair
      bytes memory actions = new bytes(2);
      actions[0] = bytes1(0x02); // MINT_POSITION
      actions[1] = bytes1(0x0d);    // SETTLE_PAIR = 0x0d,
      //  actions[2] = bytes1(0x14); // SWEEP NO ETH NO SWEEP
      //actions[3] = bytes1(0x16); // UNWRAP

      /// @notice Parameters for position manager actions
      bytes[] memory params = new bytes[](2); // new bytes[](3) for ETH liquidity positions
      params[0] = abi.encode(poolKey, MIN_TICK, MAX_TICK, liquidityDelta-1, amount0, amount1, toSendNFTto, bytes(""));
      params[1] = abi.encode(token0, token1);
      //  params[2] = abi.encode(address(0), msg.sender); // NO ETH NO SWEEP

      /// @notice Transaction deadline
      uint256 deadline = block.timestamp + 160;

      /// @notice ETH value to pass (0 for ERC20 tokens)
      uint256 valueToPass = 0;

      /// @notice Next token ID that will be minted
      uint nextID = nextIDis();
      positionManager.modifyLiquidities{value: 0}(
         abi.encode(actions, params),
         deadline
      );

      emit PositionCreated(nextID);
      return true;
   }


   /// @notice Collects accumulated fees from a Uniswap V4 position
   /// @param tokenId The ID of the position to collect fees from
   /// @param token Address of the ERC20 token in the ETH/token pair
   /// @param feesGoToWho Address to receive the collected fees
   /// @return bool Returns true if fee collection is successful
   function getUnsiwapv4Fees(uint tokenId, address token, address feesGoToWho) public payable returns (bool)
   {
      // For ETH liquidity positions
         
      // Actions
      // MINT_POSITION = 0x02,
      // SETTLE_PAIR = 0x0d,
      //SWEEP = 0x14,
      /// @notice Currency wrapper for native ETH
      Currency currency0 = Currency.wrap(address(0)); // tokenAddress1 = 0 for native ETH
      /// @notice Currency wrapper for the ERC20 token
      Currency currency1 = Currency.wrap(token);
      /// @notice Parameters for position manager actions
      bytes[] memory params = new bytes[](2);
      /// @notice Actions to perform: decrease liquidity (0) and take pair
      bytes memory actions = abi.encodePacked(uint8(0x01), uint8(0x11));/// @dev collecting fees is achieved with liquidity=0, the second parameter
      params[0] = abi.encode(tokenId, 0, 0, 0, bytes(""));
      params[1] = abi.encode(currency0, currency1, feesGoToWho);
      /// @notice Transaction deadline
      uint256 deadline = block.timestamp + 160;
      /// @notice Next token ID that will be minted
      
      positionManager.modifyLiquidities{value: 0}(
         abi.encode(actions, params),
         deadline
      );
      return true;
   }


   /// @notice Mask for extracting 32-bit offset or length values from encoded data
   uint256 constant OFFSET_OR_LENGTH_MASK = 0xffffffff;
   /// @notice Mask for word-aligned offset or length values (32-byte aligned)
   uint256 constant OFFSET_OR_LENGTH_MASK_AND_WORD_ALIGN = 0xffffffe0;
   /// @notice equivalent to SliceOutOfBounds.selector, stored in least-significant bits
   uint256 constant SLICE_ERROR_SELECTOR = 0x3b99b53d;
   
   /// @notice Decode the `_arg`-th element in `_bytes` as `bytes`
   /// @param _bytes The input bytes string to extract a bytes string from
   /// @param _arg The index of the argument to extract
   /// @return res The extracted bytes string as calldata
   function toBytes(bytes calldata _bytes, uint256 _arg) internal pure returns (bytes calldata res)
   {
      uint256 length;
      assembly ("memory-safe") {
         // The offset of the `_arg`-th element is `32 * arg`, which stores the offset of the length pointer.
         // shl(5, x) is equivalent to mul(32, x)
         let lengthPtr :=
            add(_bytes.offset, and(calldataload(add(_bytes.offset, shl(5, _arg))), OFFSET_OR_LENGTH_MASK))
         // the number of bytes in the bytes string
         length := and(calldataload(lengthPtr), OFFSET_OR_LENGTH_MASK)
         // the offset where the bytes string begins
         let offset := add(lengthPtr, 0x20)
         // assign the return parameters
         res.length := length
         res.offset := offset
         // if the provided bytes string isnt as long as the encoding says, revert
         if lt(add(_bytes.length, _bytes.offset), add(length, offset)) {
            mstore(0, SLICE_ERROR_SELECTOR)
            revert(0x1c, 4)
         }
      }
   }
   
   /// @notice Decodes mint position parameters from encoded bytes
   /// @dev equivalent to: abi.decode(params, (PoolKey, int24, int24, uint256, uint128, uint128, address, bytes)) in calldata
   /// @param params The encoded parameters as calldata bytes
   /// @return poolKey The pool key structure
   /// @return tickLower The lower tick boundary
   /// @return tickUpper The upper tick boundary
   /// @return liquidity The amount of liquidity
   /// @return amount0Max Maximum amount of token0
   /// @return amount1Max Maximum amount of token1
   /// @return owner The position owner address
   /// @return hookData Additional hook data as bytes
   function decodeMintParams(bytes calldata params) internal pure returns (
         PoolKey calldata poolKey,
         int24 tickLower,
         int24 tickUpper,
         uint256 liquidity,
         uint128 amount0Max,
         uint128 amount1Max,
         address owner,
         bytes calldata hookData
      )
   {
      // no length check performed, as there is a length check in `toBytes`
      assembly ("memory-safe") {
         poolKey := params.offset
         tickLower := calldataload(add(params.offset, 0xa0))
         tickUpper := calldataload(add(params.offset, 0xc0))
         liquidity := calldataload(add(params.offset, 0xe0))
         amount0Max := calldataload(add(params.offset, 0x100))
         amount1Max := calldataload(add(params.offset, 0x120))
         owner := calldataload(add(params.offset, 0x140))
      }
      hookData = toBytes(params, 11); // Changed from params.toBytes(11) to toBytes(params, 11)
   }


   /// @notice Calculates token amounts for a percentage of liquidity in a position
   /// @param token Address of the first token in the pair
   /// @param token2 Address of the second token in the pair
   /// @param percentagedivby10000 Percentage of liquidity divided by 10000 (e.g., 2500 = 25%)
   /// @param tokenID ID of the position to calculate amounts for
   /// @param HookAddress Address of the hook contract for the pool
   /// @return amount0 Amount of token0 for the specified liquidity percentage
   /// @return amount1 Amount of token1 for the specified liquidity percentage
   function getAmount0andAmount1forLiquidityPercentage(address token, address token2, uint128 percentagedivby10000, uint tokenID, address HookAddress) public view returns (uint amount0, uint amount1)
   {
      // Determine correct token ordering for the pool
      /// @notice Sorted token addresses (token0 must be < token1)
      (address token0, address token1) = token < token2
         ? (token, token2)
         : (token2, token);
      
      /// @notice Lower tick for full range position
      int24 tickLower = -887220; // Your desired lower tick
      /// @notice Upper tick for full range position
      int24 tickUpper = 887220;  // Your desired upper tick
      // Convert ticks to sqrtPriceX96 values
      /// @notice Sqrt ratio at lower tick
      uint160 sqrtRatioAX96 = getSqrtRatioAtTick(tickLower);
      /// @notice Sqrt ratio at upper tick
      uint160 sqrtRatioBX96 = getSqrtRatioAtTick(tickUpper);
      /// @notice Pool key structure for the token pair
      PoolKey memory poolKey = PoolKey(
         Currency.wrap(address(token0)), 
         Currency.wrap(address(token1)), 
         0x800000, 
         60, 
         IHooks(HookAddress)
      );
      /// @notice Pool ID derived from pool key
      bytes32 idz = toId(poolKey);
      
      /// @notice Current sqrt price from pool state
      (uint160 sqrtPricex96,,,) = stateView.getSlot0(idz);
      // Check if NFT is full-range
      /// @notice Current liquidity amount in the position
      ( uint128 liquidity ) = 
         positionManager.getPositionLiquidity(tokenID);
      /// @notice Amount of liquidity for the specified percentage
      uint128 liqtoRemove = liquidity * percentagedivby10000 / 10000;
      amount0 = getAmount0ForLiquidity(sqrtPricex96,sqrtRatioBX96,  liqtoRemove);
      amount1 = getAmount1ForLiquidity(sqrtRatioAX96,sqrtPricex96,  liqtoRemove);
   }
   
   
   /// @notice Resolution constant for price calculations (96 bits for X96 format)
   uint8 internal constant RESOLUTION = 96;

   /// @notice Calculates the amount of token0 for a given liquidity amount
   /// @param sqrtPriceAX96 Sqrt price at the lower bound in X96 format
   /// @param sqrtPriceBX96 Sqrt price at the upper bound in X96 format
   /// @param liquidity Amount of liquidity to calculate token0 amount for
   /// @return uint Amount of token0 corresponding to the liquidity
   function getAmount0ForLiquidity(uint160 sqrtPriceAX96, uint160 sqrtPriceBX96, uint128 liquidity) public pure returns (uint)
   {
      if (sqrtPriceAX96 > sqrtPriceBX96) (sqrtPriceAX96, sqrtPriceBX96) = (sqrtPriceBX96, sqrtPriceAX96);
      return mulDiv(
         uint256(liquidity) << RESOLUTION, sqrtPriceBX96 - sqrtPriceAX96, sqrtPriceBX96
      ) / sqrtPriceAX96;
   }
   
   
   /// @notice Calculates the amount of token1 for a given liquidity amount
   /// @param sqrtPriceAX96 Sqrt price at the lower bound in X96 format
   /// @param sqrtPriceBX96 Sqrt price at the upper bound in X96 format
   /// @param liquidity Amount of liquidity to calculate token1 amount for
   /// @return amount1 Amount of token1 corresponding to the liquidity
   function getAmount1ForLiquidity(uint160 sqrtPriceAX96, uint160 sqrtPriceBX96, uint128 liquidity)public pure returns (uint256 amount1)
   {
      if (sqrtPriceAX96 > sqrtPriceBX96) (sqrtPriceAX96, sqrtPriceBX96) = (sqrtPriceBX96, sqrtPriceAX96);
      return mulDiv(liquidity, sqrtPriceBX96 - sqrtPriceAX96, Q96);
   }
   
   




// Convert tick to sqrtPriceX96
function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160) {
    uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));
    require(absTick <= uint256(int256(MAX_TICK)), "TICK_OUT_OF_RANGE");

    uint256 ratio = absTick & 0x1 != 0 
        ? 0xfffcb933bd6fad37aa2d162d1a594001 
        : 0x100000000000000000000000000000000;
    if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;
    if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;
    if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;
    if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;
    if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;
    if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;
    if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;
    if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;
    if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;
    if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;
    if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;
    if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;
    if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;
    if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;
    if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;
    if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;
    if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;
    if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;
    if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;

    if (tick > 0) ratio = type(uint256).max / ratio;

    // This divides by 1<<32 rounding up to go from a Q128.128 to a Q96.64
    uint256 sqrtPriceX96 = uint256((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));
    
    return uint160(sqrtPriceX96);
}





    fallback() external payable {
        // Optional: handle unexpected data
    }

    receive() external payable {
    }
}




/*
*
* 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":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"SafeCastOverflow","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"PositionCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"tokenIn","type":"address"},{"indexed":true,"internalType":"address","name":"tokenOut","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOut","type":"uint256"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"SwapExecuted","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"IV4UniswapRouter","outputs":[{"internalType":"contract IV4Router","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"contract IWETH","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"token2","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountIn2","type":"uint256"},{"internalType":"uint256","name":"currentx96","type":"uint256"},{"internalType":"uint256","name":"slippage","type":"uint256"},{"internalType":"address","name":"hookAddress","type":"address"},{"internalType":"address","name":"toSendNFTto","type":"address"}],"name":"createPositionWith2Tokens","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint160","name":"sqrtPriceAX96","type":"uint160"},{"internalType":"uint160","name":"sqrtPriceBX96","type":"uint160"},{"internalType":"uint128","name":"liquidity","type":"uint128"}],"name":"getAmount0ForLiquidity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"token2","type":"address"},{"internalType":"uint128","name":"percentagedivby10000","type":"uint128"},{"internalType":"uint256","name":"tokenID","type":"uint256"},{"internalType":"address","name":"HookAddress","type":"address"}],"name":"getAmount0andAmount1forLiquidityPercentage","outputs":[{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint160","name":"sqrtPriceAX96","type":"uint160"},{"internalType":"uint160","name":"sqrtPriceBX96","type":"uint160"},{"internalType":"uint128","name":"liquidity","type":"uint128"}],"name":"getAmount1ForLiquidity","outputs":[{"internalType":"uint256","name":"amount1","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint160","name":"sqrtPriceX96","type":"uint160"},{"internalType":"uint160","name":"sqrtPriceAX96","type":"uint160"},{"internalType":"uint160","name":"sqrtPriceBX96","type":"uint160"},{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"}],"name":"getLiquidityForAmounts","outputs":[{"internalType":"uint128","name":"liquidity","type":"uint128"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"tokenZeroxBTC","type":"address"},{"internalType":"address","name":"tokenBZeroX","type":"address"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"hookAddress","type":"address"},{"internalType":"uint128","name":"amountIn","type":"uint128"}],"name":"getOutput","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"address","name":"hookAddress","type":"address"}],"name":"getPoolKey","outputs":[{"components":[{"internalType":"Currency","name":"currency0","type":"address"},{"internalType":"Currency","name":"currency1","type":"address"},{"internalType":"uint24","name":"fee","type":"uint24"},{"internalType":"int24","name":"tickSpacing","type":"int24"},{"internalType":"contract IHooks","name":"hooks","type":"address"}],"internalType":"struct PoolKey","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"token2","type":"address"},{"internalType":"address","name":"hookAddress","type":"address"}],"name":"getPriceRatio","outputs":[{"internalType":"uint256","name":"ratio","type":"uint256"},{"internalType":"address","name":"token0z","type":"address"},{"internalType":"address","name":"token1z","type":"address"},{"internalType":"uint8","name":"token0decimals","type":"uint8"},{"internalType":"uint8","name":"token1decimals","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint160","name":"sqrtPriceX96","type":"uint160"},{"internalType":"uint8","name":"decimals","type":"uint8"}],"name":"getPriceRatioWithDecimals","outputs":[{"internalType":"uint256","name":"priceRatio","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"feesGoToWho","type":"address"}],"name":"getUnsiwapv4Fees","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"token2","type":"address"},{"internalType":"address","name":"hookAddress","type":"address"}],"name":"getsqrtPricex96","outputs":[{"internalType":"uint160","name":"","type":"uint160"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextIDis","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"permit2","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolManager","outputs":[{"internalType":"contract IPoolManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"positionManager","outputs":[{"internalType":"contract IPositionManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"quoter","outputs":[{"internalType":"contract IUniswapV4Quoter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stateView","outputs":[{"internalType":"contract IStateView","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"minAmountOut","type":"uint256"},{"internalType":"address","name":"hookAddress","type":"address"},{"internalType":"address","name":"WhereToSendFunds","type":"address"}],"name":"swapTokenTWOTOKENS","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawETH","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenID","type":"uint256"}],"name":"withdrawNFT","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"withdrawTokens","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

0x610140806040523461016b57734a6513c898fe1b2d0e78d3b0e0a4a151589b1cba60805273571291b572ed32ce6751a2cb2486ebee8defb9b460a052734b2c77d209d3405f41a037ec6c77f7f5b8e2ca8060c0527305e73354cfdd6745c338b50bcfdfa3aa6fa0340860e05273492e6456d9528771018deb9e87ef7750ef1841046101005273fff9976782d46cc05630d1f6ebab18b2324d6b1461012052600080546001600160a01b03199081166e22d473030f116ddee9f6b43ac78ba317909155600180549091163317905561288290816101718239608051818181610a730152611c72015260a051818181610d7c0152818161150d015281816116630152818161188f01526119cb015260c051818181610c51015281816112e8015281816113b301528181611a1a01528181611e4f0152612519015260e05181610a2e015261010051818181610201015281816105940152818161060c0152611df401526101205181610ab80152f35b600080fdfe6080604052600436101561000f57005b6000803560e01c8063023245d714611e235780630c8afd1b14611dde57806312261ee714611db7578063150b7a0214611d4557806315925f1514611d015780631b2b5ae614611b6257806329e24cb714611b2d5780634140f491146118fb578063473dcd8c146117ea57806348195439146117b657806349df728c146116925780634c4a3c251461164d57806355fa114c146114655780636098fd4a146114175780636ac69a8e146113e2578063791b98bc1461139d578063871ec337146111e657806391b84088146111c3578063a5e435ee14610ae7578063ad5c464814610aa2578063c6bbd5a714610a5d578063dc4c90d314610a18578063e086e5ec146109635763feec086e1461011f57005b346109605761010036600319011261096057610139611f3b565b90610142611f51565b9161014b611f67565b91610154611f7d565b61015c611f93565b93610165611fa9565b936001600160a01b03878116908216101561095a575b835460405163095ea7b360e01b81526001600160a01b03918216600482015260001960248201529060209082906044908290899088165af180156109195761093d575b5083546001600160a01b03166101db4265ffffffffffff16612590565b813b1561084d576040516387517c4560e01b8152918691839190829084908290610233907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168b600485016125ad565b03925af1801561091957908591610924575b50506040516323b872dd60e01b81523360048201523060248201526084356044820152602081606481886001600160a01b0388165af18015610919576108fc575b506040958651610296888261206d565b60018152601f198801903690602001378651600160fc1b602082015260018152906102c260218361206d565b8751926102cf898561206d565b6003845260208401601f198a013682378451156108e857600690538351600110156108d457600c60218501538351600210156108d457600f60228501538851996001600160a01b039190911691906103268b612051565b828b526001600160a01b039081166020808d0191909152628000008b8d0152603c60608d0152911660808b01528851909990918a9190610366838561206d565b8884528a519361037585612051565b8285526001600160a01b0388168214848601526001600160801b0360843581168d87015260a43516606086015260808501528a518084018490528451909485916103c290838f0190611fbf565b84810151151560e08301528c8101516001600160801b031661010083015260608101516001600160801b03166101208301526080015161014082016101209052610160820161041091612112565b03601f1981018552610422908561206d565b61046f916104c9916001600160a01b03891681036108bc57815161047d906001600160a01b03168e5b516001600160a01b0390911687820190815260843560208201529095869160400190565b03601f19810186528561206d565b6001600160a01b038916036108ad57602001516001600160a01b03165b8b516001600160a01b0390911693810193845260a435602085015292839060400103601f19810184528361206d565b89519260608c016104da818661206d565b60038552601f19018c8a5b82811061089e575050506104f884612427565b5261050283612427565b5061050c8361244a565b526105168261244a565b506105208261245a565b5261052a8161245a565b5087519260208a0161053c818661206d565b60018552601f19018a885b82811061086557505050610573906105658a519384928d84016124c3565b03601f19810183528261206d565b61057c83612427565b5261058682612427565b50603c4201804211610851577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163b1561084d5785916105ed916105ff8a519586948594630d64d59360e21b8652606060048701526064860190612112565b8481036003190160248601529061246a565b60448301919091520381837f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af180156107b857908491610834575b505084516370a0823160e01b81523060048201529186836024816001600160a01b0386165afa9283156107b8578493610805575b5085516370a0823160e01b8152306004820152926001600160a01b039190911691908784602481865afa9384156107fb579185918995949383956107c2575b508061074e575b505050816106d0575b82865160018152f35b855163a9059cbb60e01b81526001600160a01b0395909516600486015260248501919091528390604490829085905af19081156107435750610716575b808381806106c7565b61073590833d851161073c575b61072d818361206d565b810190612296565b503861070d565b503d610723565b8351903d90823e3d90fd5b885163a9059cbb60e01b81526001600160a01b03898116600483015260248201929092529495939493928492604492849291165af180156107b857908793929161079b575b8085916106be565b6107b190843d861161073c5761072d818361206d565b5038610793565b86513d86823e3d90fd5b925093509381813d83116107f4575b6107db818361206d565b810103126107ef57879385915193386106b7565b600080fd5b503d6107d1565b87513d87823e3d90fd5b9092508681813d831161082d575b61081d818361206d565b810103126107ef57519138610678565b503d610813565b8161083e9161206d565b610849578238610644565b8280fd5b8580fd5b634e487b7160e01b86526011600452602486fd5b60608782018301528101610547565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b81526041600452602490fd5b606087820183015281016104e5565b516001600160a01b031661049a565b602082015161047d906001600160a01b03168e61044b565b634e487b7160e01b87526032600452602487fd5b634e487b7160e01b88526032600452602488fd5b6109149060203d60201161073c5761072d818361206d565b610286565b6040513d87823e3d90fd5b8161092e9161206d565b610939578338610245565b8380fd5b6109559060203d60201161073c5761072d818361206d565b6101be565b9561017b565b80fd5b50346109605780600319360112610960578080808060018060a01b036001541661098e813314612018565b47905af1903d15610a12573d9067ffffffffffffffff821161088a57604051916109c2601f8201601f19166020018461206d565b825260203d92013e5b156109db57602060405160018152f35b60405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b6044820152606490fd5b506109cb565b50346109605780600319360112610960576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b50346109605780600319360112610960576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b50346109605780600319360112610960576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5061010036600319011261096057610afd611f3b565b90610b06611f51565b91604435606435906084359460a43595610b1e611f93565b94610b27611fa9565b936001600160a01b03848116908316109182156111bd5793915b156111b75794975b6040516323b872dd60e01b8152336004820152306024820152604481018790526001600160a01b03851693906020816064818d895af180156110e85761119a575b506040516323b872dd60e01b8152336004820152306024820152604481018b90526001600160a01b03841693906020816064818e895af180156111555761117d575b50895460405163095ea7b360e01b81526001600160a01b039091166004820152602481018990526020816044818e8a5af1801561115557611160575b50895460405163095ea7b360e01b81526001600160a01b039091166004820152602481018c90526020816044818e895af1801561115557611138575b5089546001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169765ffffffffffff421692909116610c8983612590565b91813b1561113457918d918a83610cb795604051968795869485936387517c4560e01b8552600485016125ad565b03925af1801561112957908c91611110575b50508a546001600160a01b031690610ce090612590565b91813b1561110c57918b918883610d0e95604051968795869485936387517c4560e01b8552600485016125ad565b03925af180156110e857908a916110f3575b505060405197610d2f89612051565b8489528360208a01526280000060408a0152603c60608a015260018060a01b0316608089015260a088209160405192633205590760e21b8452600484015260808360248160018060a01b037f0000000000000000000000000000000000000000000000000000000000000000165afa9283156110e8578a936110b4575b506001600160a01b038316916127108281039081116110a057610dd2612710918361221f565b0491612710019081612710116110a05761271091610def9161221f565b04908210159182611095575b50501561104257610e4089876001600160801b0393610e25640100ad139c6001600160a01b031690565b73ff53611968f1e5ca45cfca7918447e7f5776f6d4916122c7565b1695604095865197610e52888a61206d565b6002895260208901601f19890136823789511561102e576002905388516001101561101a57600d60218a0153610e866123ec565b9660001982019182116110065760209b8c938a5193610ea5868661206d565b8d85528b519687968701610eb891611fbf565b620d89b31960c0870152620d89b460e08701526101008601526101208501526101408401526001600160a01b031661016083015261018080830152610f02906101a0830190612112565b03601f1981018252610f14908261206d565b610f1d85612427565b52610f2784612427565b508451918883015284820152838152610f4160608261206d565b610f4a8361244a565b52610f548261244a565b504260a0019182421161085157610f7d610f6c612504565b9561056586519384928b84016124c3565b813b1561084d57918591610fa79383865180968195829463dd46508f60e01b8452600484016124e8565b03925af18015610ffc57908491610fe7575b50507f97c3f5c9077358c7266488de6a3ebba41df38417797d90b665239fcb506c840a90519280a260018152f35b81610ff19161206d565b610849578238610fb9565b82513d86823e3d90fd5b634e487b7160e01b8b52601160045260248bfd5b634e487b7160e01b8a52603260045260248afd5b634e487b7160e01b8b52603260045260248bfd5b60405162461bcd60e51b815260206004820152602560248201527f5072696365206d6f766564206265796f6e6420736c69707061676520746f6c6560448201526472616e636560d81b6064820152608490fd5b111590503880610dfb565b634e487b7160e01b8c52601160045260248cfd5b6110d791935060803d6080116110e1575b6110cf818361206d565b8101906121d8565b5050509138610dac565b503d6110c5565b6040513d8c823e3d90fd5b816110fd9161206d565b611108578838610d20565b8880fd5b8b80fd5b8161111a9161206d565b611125578a38610cc9565b8a80fd5b6040513d8e823e3d90fd5b8d80fd5b6111509060203d60201161073c5761072d818361206d565b610c44565b6040513d8d823e3d90fd5b6111789060203d60201161073c5761072d818361206d565b610c08565b6111959060203d60201161073c5761072d818361206d565b610bcc565b6111b29060203d60201161073c5761072d818361206d565b610b8a565b97610b49565b91610b41565b503461096057806003193601126109605760206111de612504565b604051908152f35b506060366003190112610960576111fb611f51565b90611204611f67565b9161120d6123ec565b604051600160f81b6020820152601160f81b602182015260028152909161123560228361206d565b60209461056561127d60405161124b898261206d565b8781526040519283916004358b84015289604084015289606084015289608084015260a08084015260c0830190612112565b61128685612427565b5261129084612427565b5060405191858784015260018060a01b0316604083015260018060a01b03166060820152606081526112c360808261206d565b6112cc8361244a565b526112d68261244a565b5060a0420191824211611389576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316929091611325918391610565918984016124c3565b813b1561093957918391611350938360405180968195829463dd46508f60e01b8452600484016124e8565b03925af1801561137e57611369575b8260405160018152f35b61137482809261206d565b610960578061135f565b6040513d84823e3d90fd5b634e487b7160e01b84526011600452602484fd5b50346109605780600319360112610960576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b50346109605760603660031901126109605760206111de611401611f3b565b611409611f51565b611411612002565b91612363565b50346109605760a0366003190112610960576020611454611436611f3b565b61143e611f51565b90611447611f67565b60843592606435926122c7565b6001600160801b0360405191168152f35b50346109605760603660031901126109605761147f611f3b565b611487611f51565b61148f611f67565b916001600160a01b0382811690821610156116445760a0905b600180831b031691600180831b031692604051906114c582612051565b838252846020830152628000006040830152603c6060830152600180841b031660808201522060405190633205590760e21b8252600482015260808160248160018060a01b037f0000000000000000000000000000000000000000000000000000000000000000165afa801561163957611546918591611617575b50612232565b9160405163313ce56760e01b8152602081600481865afa9081156109195785916115f8575b5060405163313ce56760e01b815291602083600481845afa9283156115ed579060ff9493929160a097936115bc575b5084929360405196875260208701526040860152166060840152166080820152f35b8593506115e09060203d6020116115e6575b6115d8818361206d565b8101906122ae565b9261159a565b503d6115ce565b6040513d88823e3d90fd5b611611915060203d6020116115e6576115d8818361206d565b3861156b565b611630915060803d6080116110e1576110cf818361206d565b50505038611540565b6040513d86823e3d90fd5b9060a0906114a8565b50346109605780600319360112610960576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5034610960576020366003190112610960576116ac611f3b565b6001546001600160a01b031691906116c5338414612018565b6040516370a0823160e01b81523060048201526001600160a01b039190911692602082602481875afa9182156117ab578392611775575b5060405163a9059cbb60e01b81526001600160a01b0390911660048201526024810191909152916020908390818481604481015b03925af1908115611769575061174c575b602060405160018152f35b6117649060203d60201161073c5761072d818361206d565b611741565b604051903d90823e3d90fd5b91506020823d6020116117a3575b816117906020938361206d565b810103126107ef579051906117306116fc565b3d9150611783565b6040513d85823e3d90fd5b5034610960576040366003190112610960576117d0611f3b565b6024359160ff831683036109605760206111de8484612262565b50346109605760603660031901126109605760a0611806611f3b565b61180e611f51565b90611817611f67565b906000196001851b0183811690821610156118f657915b6040519261183b84612051565b600180861b03168352600180851b03166020830152628000006040830152603c6060830152600180841b031660808201522060405190633205590760e21b8252600482015260808160248160018060a01b037f0000000000000000000000000000000000000000000000000000000000000000165afa90811561137e57602092916118d4575b506040516001600160a01b039091168152f35b6118ed915060803d6080116110e1576110cf818361206d565b505050386118c1565b61182e565b50346109605760a036600319011261096057611915611f3b565b61191d611f51565b91611926612002565b906084359260018060a01b038416809403611b29576001600160a01b038581169082161015611b205760a0905b640100ad139c9473ff53611968f1e5ca45cfca7918447e7f5776f6d4966040519261197d84612051565b600180861b03168352600180851b03166020830152628000006040830152603c60608301526080820152209160405192633205590760e21b8452600484015260808360248160018060a01b037f0000000000000000000000000000000000000000000000000000000000000000165afa92831561137e578293611afc575b50604051631efeed3360e01b81526064356004820152906020826024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa9182156117ab578392611ab1575b506001600160801b03809116911602906001600160801b038216918203611a9d575092611a9191611a8b61271060409604809383612363565b93612182565b82519182526020820152f35b634e487b7160e01b81526011600452602490fd5b9091506020813d602011611af4575b81611acd6020938361206d565b8101031261084957516001600160801b038116810361084957906001600160801b03611a52565b3d9150611ac0565b611b1691935060803d6080116110e1576110cf818361206d565b50505091386119fb565b9360a090611953565b5080fd5b50346109605760603660031901126109605760206111de611b4c611f3b565b611b54611f51565b611b5c612002565b91612182565b50346109605760a036600319011261096057611b7c611f3b565b90611b85611f51565b611b8d611f67565b90611b96611f7d565b90608435946001600160801b038616809603611cfd5790611bb7929161208f565b80516040516020956001600160a01b03948516929094169190911492611bdd868361206d565b848252604051926080840184811067ffffffffffffffff821117611ce957926001600160801b0360409593611c6d93611c499688528552898501978852868501908152606085019283528651978896879663aa9d21cb60e01b88528c6004890152602488019051611fbf565b51151560c4860152511660e484015251610100610104840152610124830190612112565b0381857f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af1918215611769578092611cb4575b5050604051908152f35b9091506040823d604011611ce1575b81611cd06040938361206d565b810103126109605750513880611caa565b3d9150611cc3565b634e487b7160e01b87526041600452602487fd5b8480fd5b50346109605760603660031901126109605760a0611d36611d20611f3b565b611d28611f51565b611d30611f67565b9161208f565b611d436040518092611fbf565bf35b503461096057608036600319011261096057611d5f611f3b565b50611d68611f51565b5060643567ffffffffffffffff8111611b295736602382011215611b2957806004013567ffffffffffffffff8111610849573691016024011161096057604051630a85bd0160e11b8152602090f35b5034610960578060031936011261096057546040516001600160a01b039091168152602090f35b50346109605780600319360112610960576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b503461096057602036600319011261096057600435611e4d60018060a01b03600154163314612018565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690813b156108495760405163095ea7b360e01b815230600482015260248101829052838160448183875af1801561163957611f27575b506001546001600160a01b031691839190803b1561084957604051632142170760e11b81523060048201526001600160a01b0394909416602485015260448401919091528290606490829084905af1801561137e57611f12575b602082604051908152f35b611f1d82809261206d565b6109605738611f07565b83611f349194929461206d565b9138611ead565b600435906001600160a01b03821682036107ef57565b602435906001600160a01b03821682036107ef57565b604435906001600160a01b03821682036107ef57565b606435906001600160a01b03821682036107ef57565b60c435906001600160a01b03821682036107ef57565b60e435906001600160a01b03821682036107ef57565b80516001600160a01b03908116835260208083015182169084015260408083015162ffffff169084015260608083015160020b9084015260809182015116910152565b604435906001600160801b03821682036107ef57565b1561201f57565b60405162461bcd60e51b815260206004820152600a60248201526927b7363c9027bbb732b960b11b6044820152606490fd5b60a0810190811067ffffffffffffffff82111761087457604052565b90601f8019910116810190811067ffffffffffffffff82111761087457604052565b919091600060806040516120a281612051565b82815260208101839052604081018390526060810183905201526001600160a01b03838116908216101561210d57915b604051926120df84612051565b6001600160a01b0390811684529081166020840152628000006040840152603c606084015216608082015290565b6120d2565b919082519283825260005b84811061213e575050826000602080949584010152601f8019910116010190565b8060208092840101518282860101520161211d565b6001600160a01b03918216908216039190821161216c57565b634e487b7160e01b600052601160045260246000fd5b6121bf92916001600160801b03916001600160a01b03808316908216116121c2575b6001600160a01b03916121b79190612153565b1691166125dc565b90565b906121a4565b519062ffffff821682036107ef57565b91908260809103126107ef5781516001600160a01b03811681036107ef579160208101518060020b81036107ef57916121bf6060612218604085016121c8565b93016121c8565b8181029291811591840414171561216c57565b6001600160a01b0316801561225c57670de0b6b3a76400006122576121bf928061221f565b612626565b50600090565b6001600160a01b031690811561228f5760ff1690604d821161216c576122576121bf92600a0a918061221f565b5050600090565b908160209103126107ef575180151581036107ef5790565b908160209103126107ef575160ff811681036107ef5790565b936001600160a01b038381169083161161235b575b6001600160a01b038581169590831686116122fd5750506121bf93506127ba565b919490939192906001600160a01b038216111561234f5782916123249161232a95946127ba565b93612780565b6001600160801b0381166001600160801b0383161060001461234a575090565b905090565b9150506121bf92612780565b9091906122dc565b916123ba916001600160a01b03808216908516116123e6575b6001600160a01b0361238e8583612153565b6001600160a01b039092169291169060601b6fffffffffffffffffffffffffffffffff60601b166126fd565b6001600160a01b039091169081156123d0570490565b634e487b7160e01b600052601260045260246000fd5b9261237c565b604051606091906123fd838261206d565b6002815291601f19018260005b82811061241657505050565b80606060208093850101520161240a565b8051156124345760200190565b634e487b7160e01b600052603260045260246000fd5b8051600110156124345760400190565b8051600210156124345760600190565b9080602083519182815201916020808360051b8301019401926000915b83831061249657505050505090565b90919293946020806124b4600193601f198682030187528951612112565b97019301930191939290612487565b90916124da6121bf93604084526040840190612112565b91602081840391015261246a565b9291906124ff602091604086526040860190612112565b930152565b604051631d5e528f60e21b81526020816004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa90811561258457600091612555575090565b90506020813d60201161257c575b816125706020938361206d565b810103126107ef575190565b3d9150612563565b6040513d6000823e3d90fd5b65ffffffffffff610e109116019065ffffffffffff821161216c57565b6001600160a01b0391821681529181166020830152604082015265ffffffffffff909116606082015260800190565b818102919060001982820991838084109303928084039384600160601b11156107ef571461261d57600160601b910990828211900360a01b910360601c1790565b50505060601c90565b818102919060001982820991838084109303928084039384600160c01b11156107ef571461266757600160c01b910990828211900360401b910360c01c1790565b50505060c01c90565b90606082901b90600019600160601b8409928280851094039380850394858411156107ef57146126f6578190600160601b9009818060000316809204600281600302188082026002030280820260020302808202600203028082026002030280820260020302809102600203029360018380600003040190848311900302920304170290565b5091500490565b9181830291600019818509938380861095039480860395868511156107ef57146127785790829109818060000316809204600281600302188082026002030280820260020302808202600203028082026002030280820260020302809102600203029360018380600003040190848311900302920304170290565b505091500490565b6121bf926127af9290916001600160a01b03808316908216116127b4575b90036001600160a01b031690612670565b612807565b9061279e565b6121bf926127af929091906001600160a01b0380821690831611612801575b6127ef6001600160a01b038281169084166125dc565b9190036001600160a01b0316916126fd565b906127d9565b906001600160801b03821680920361281b57565b60405162461bcd60e51b81526020600482015260096024820152681b9bdd08195c5d585b60ba1b6044820152606490fdfea264697066735822122045fe6b8813aecac364e4fab20dd37159ac9ca490df7b6be67a140c1c608232c864736f6c634300081c0033

Deployed Bytecode

0x6080604052600436101561000f57005b6000803560e01c8063023245d714611e235780630c8afd1b14611dde57806312261ee714611db7578063150b7a0214611d4557806315925f1514611d015780631b2b5ae614611b6257806329e24cb714611b2d5780634140f491146118fb578063473dcd8c146117ea57806348195439146117b657806349df728c146116925780634c4a3c251461164d57806355fa114c146114655780636098fd4a146114175780636ac69a8e146113e2578063791b98bc1461139d578063871ec337146111e657806391b84088146111c3578063a5e435ee14610ae7578063ad5c464814610aa2578063c6bbd5a714610a5d578063dc4c90d314610a18578063e086e5ec146109635763feec086e1461011f57005b346109605761010036600319011261096057610139611f3b565b90610142611f51565b9161014b611f67565b91610154611f7d565b61015c611f93565b93610165611fa9565b936001600160a01b03878116908216101561095a575b835460405163095ea7b360e01b81526001600160a01b03918216600482015260001960248201529060209082906044908290899088165af180156109195761093d575b5083546001600160a01b03166101db4265ffffffffffff16612590565b813b1561084d576040516387517c4560e01b8152918691839190829084908290610233907f000000000000000000000000492e6456d9528771018deb9e87ef7750ef1841046001600160a01b03168b600485016125ad565b03925af1801561091957908591610924575b50506040516323b872dd60e01b81523360048201523060248201526084356044820152602081606481886001600160a01b0388165af18015610919576108fc575b506040958651610296888261206d565b60018152601f198801903690602001378651600160fc1b602082015260018152906102c260218361206d565b8751926102cf898561206d565b6003845260208401601f198a013682378451156108e857600690538351600110156108d457600c60218501538351600210156108d457600f60228501538851996001600160a01b039190911691906103268b612051565b828b526001600160a01b039081166020808d0191909152628000008b8d0152603c60608d0152911660808b01528851909990918a9190610366838561206d565b8884528a519361037585612051565b8285526001600160a01b0388168214848601526001600160801b0360843581168d87015260a43516606086015260808501528a518084018490528451909485916103c290838f0190611fbf565b84810151151560e08301528c8101516001600160801b031661010083015260608101516001600160801b03166101208301526080015161014082016101209052610160820161041091612112565b03601f1981018552610422908561206d565b61046f916104c9916001600160a01b03891681036108bc57815161047d906001600160a01b03168e5b516001600160a01b0390911687820190815260843560208201529095869160400190565b03601f19810186528561206d565b6001600160a01b038916036108ad57602001516001600160a01b03165b8b516001600160a01b0390911693810193845260a435602085015292839060400103601f19810184528361206d565b89519260608c016104da818661206d565b60038552601f19018c8a5b82811061089e575050506104f884612427565b5261050283612427565b5061050c8361244a565b526105168261244a565b506105208261245a565b5261052a8161245a565b5087519260208a0161053c818661206d565b60018552601f19018a885b82811061086557505050610573906105658a519384928d84016124c3565b03601f19810183528261206d565b61057c83612427565b5261058682612427565b50603c4201804211610851577f000000000000000000000000492e6456d9528771018deb9e87ef7750ef1841046001600160a01b03163b1561084d5785916105ed916105ff8a519586948594630d64d59360e21b8652606060048701526064860190612112565b8481036003190160248601529061246a565b60448301919091520381837f000000000000000000000000492e6456d9528771018deb9e87ef7750ef1841046001600160a01b03165af180156107b857908491610834575b505084516370a0823160e01b81523060048201529186836024816001600160a01b0386165afa9283156107b8578493610805575b5085516370a0823160e01b8152306004820152926001600160a01b039190911691908784602481865afa9384156107fb579185918995949383956107c2575b508061074e575b505050816106d0575b82865160018152f35b855163a9059cbb60e01b81526001600160a01b0395909516600486015260248501919091528390604490829085905af19081156107435750610716575b808381806106c7565b61073590833d851161073c575b61072d818361206d565b810190612296565b503861070d565b503d610723565b8351903d90823e3d90fd5b885163a9059cbb60e01b81526001600160a01b03898116600483015260248201929092529495939493928492604492849291165af180156107b857908793929161079b575b8085916106be565b6107b190843d861161073c5761072d818361206d565b5038610793565b86513d86823e3d90fd5b925093509381813d83116107f4575b6107db818361206d565b810103126107ef57879385915193386106b7565b600080fd5b503d6107d1565b87513d87823e3d90fd5b9092508681813d831161082d575b61081d818361206d565b810103126107ef57519138610678565b503d610813565b8161083e9161206d565b610849578238610644565b8280fd5b8580fd5b634e487b7160e01b86526011600452602486fd5b60608782018301528101610547565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b81526041600452602490fd5b606087820183015281016104e5565b516001600160a01b031661049a565b602082015161047d906001600160a01b03168e61044b565b634e487b7160e01b87526032600452602487fd5b634e487b7160e01b88526032600452602488fd5b6109149060203d60201161073c5761072d818361206d565b610286565b6040513d87823e3d90fd5b8161092e9161206d565b610939578338610245565b8380fd5b6109559060203d60201161073c5761072d818361206d565b6101be565b9561017b565b80fd5b50346109605780600319360112610960578080808060018060a01b036001541661098e813314612018565b47905af1903d15610a12573d9067ffffffffffffffff821161088a57604051916109c2601f8201601f19166020018461206d565b825260203d92013e5b156109db57602060405160018152f35b60405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b6044820152606490fd5b506109cb565b50346109605780600319360112610960576040517f00000000000000000000000005e73354cfdd6745c338b50bcfdfa3aa6fa034086001600160a01b03168152602090f35b50346109605780600319360112610960576040517f0000000000000000000000004a6513c898fe1b2d0e78d3b0e0a4a151589b1cba6001600160a01b03168152602090f35b50346109605780600319360112610960576040517f000000000000000000000000fff9976782d46cc05630d1f6ebab18b2324d6b146001600160a01b03168152602090f35b5061010036600319011261096057610afd611f3b565b90610b06611f51565b91604435606435906084359460a43595610b1e611f93565b94610b27611fa9565b936001600160a01b03848116908316109182156111bd5793915b156111b75794975b6040516323b872dd60e01b8152336004820152306024820152604481018790526001600160a01b03851693906020816064818d895af180156110e85761119a575b506040516323b872dd60e01b8152336004820152306024820152604481018b90526001600160a01b03841693906020816064818e895af180156111555761117d575b50895460405163095ea7b360e01b81526001600160a01b039091166004820152602481018990526020816044818e8a5af1801561115557611160575b50895460405163095ea7b360e01b81526001600160a01b039091166004820152602481018c90526020816044818e895af1801561115557611138575b5089546001600160a01b037f0000000000000000000000004b2c77d209d3405f41a037ec6c77f7f5b8e2ca8081169765ffffffffffff421692909116610c8983612590565b91813b1561113457918d918a83610cb795604051968795869485936387517c4560e01b8552600485016125ad565b03925af1801561112957908c91611110575b50508a546001600160a01b031690610ce090612590565b91813b1561110c57918b918883610d0e95604051968795869485936387517c4560e01b8552600485016125ad565b03925af180156110e857908a916110f3575b505060405197610d2f89612051565b8489528360208a01526280000060408a0152603c60608a015260018060a01b0316608089015260a088209160405192633205590760e21b8452600484015260808360248160018060a01b037f000000000000000000000000571291b572ed32ce6751a2cb2486ebee8defb9b4165afa9283156110e8578a936110b4575b506001600160a01b038316916127108281039081116110a057610dd2612710918361221f565b0491612710019081612710116110a05761271091610def9161221f565b04908210159182611095575b50501561104257610e4089876001600160801b0393610e25640100ad139c6001600160a01b031690565b73ff53611968f1e5ca45cfca7918447e7f5776f6d4916122c7565b1695604095865197610e52888a61206d565b6002895260208901601f19890136823789511561102e576002905388516001101561101a57600d60218a0153610e866123ec565b9660001982019182116110065760209b8c938a5193610ea5868661206d565b8d85528b519687968701610eb891611fbf565b620d89b31960c0870152620d89b460e08701526101008601526101208501526101408401526001600160a01b031661016083015261018080830152610f02906101a0830190612112565b03601f1981018252610f14908261206d565b610f1d85612427565b52610f2784612427565b508451918883015284820152838152610f4160608261206d565b610f4a8361244a565b52610f548261244a565b504260a0019182421161085157610f7d610f6c612504565b9561056586519384928b84016124c3565b813b1561084d57918591610fa79383865180968195829463dd46508f60e01b8452600484016124e8565b03925af18015610ffc57908491610fe7575b50507f97c3f5c9077358c7266488de6a3ebba41df38417797d90b665239fcb506c840a90519280a260018152f35b81610ff19161206d565b610849578238610fb9565b82513d86823e3d90fd5b634e487b7160e01b8b52601160045260248bfd5b634e487b7160e01b8a52603260045260248afd5b634e487b7160e01b8b52603260045260248bfd5b60405162461bcd60e51b815260206004820152602560248201527f5072696365206d6f766564206265796f6e6420736c69707061676520746f6c6560448201526472616e636560d81b6064820152608490fd5b111590503880610dfb565b634e487b7160e01b8c52601160045260248cfd5b6110d791935060803d6080116110e1575b6110cf818361206d565b8101906121d8565b5050509138610dac565b503d6110c5565b6040513d8c823e3d90fd5b816110fd9161206d565b611108578838610d20565b8880fd5b8b80fd5b8161111a9161206d565b611125578a38610cc9565b8a80fd5b6040513d8e823e3d90fd5b8d80fd5b6111509060203d60201161073c5761072d818361206d565b610c44565b6040513d8d823e3d90fd5b6111789060203d60201161073c5761072d818361206d565b610c08565b6111959060203d60201161073c5761072d818361206d565b610bcc565b6111b29060203d60201161073c5761072d818361206d565b610b8a565b97610b49565b91610b41565b503461096057806003193601126109605760206111de612504565b604051908152f35b506060366003190112610960576111fb611f51565b90611204611f67565b9161120d6123ec565b604051600160f81b6020820152601160f81b602182015260028152909161123560228361206d565b60209461056561127d60405161124b898261206d565b8781526040519283916004358b84015289604084015289606084015289608084015260a08084015260c0830190612112565b61128685612427565b5261129084612427565b5060405191858784015260018060a01b0316604083015260018060a01b03166060820152606081526112c360808261206d565b6112cc8361244a565b526112d68261244a565b5060a0420191824211611389576040517f0000000000000000000000004b2c77d209d3405f41a037ec6c77f7f5b8e2ca806001600160a01b0316929091611325918391610565918984016124c3565b813b1561093957918391611350938360405180968195829463dd46508f60e01b8452600484016124e8565b03925af1801561137e57611369575b8260405160018152f35b61137482809261206d565b610960578061135f565b6040513d84823e3d90fd5b634e487b7160e01b84526011600452602484fd5b50346109605780600319360112610960576040517f0000000000000000000000004b2c77d209d3405f41a037ec6c77f7f5b8e2ca806001600160a01b03168152602090f35b50346109605760603660031901126109605760206111de611401611f3b565b611409611f51565b611411612002565b91612363565b50346109605760a0366003190112610960576020611454611436611f3b565b61143e611f51565b90611447611f67565b60843592606435926122c7565b6001600160801b0360405191168152f35b50346109605760603660031901126109605761147f611f3b565b611487611f51565b61148f611f67565b916001600160a01b0382811690821610156116445760a0905b600180831b031691600180831b031692604051906114c582612051565b838252846020830152628000006040830152603c6060830152600180841b031660808201522060405190633205590760e21b8252600482015260808160248160018060a01b037f000000000000000000000000571291b572ed32ce6751a2cb2486ebee8defb9b4165afa801561163957611546918591611617575b50612232565b9160405163313ce56760e01b8152602081600481865afa9081156109195785916115f8575b5060405163313ce56760e01b815291602083600481845afa9283156115ed579060ff9493929160a097936115bc575b5084929360405196875260208701526040860152166060840152166080820152f35b8593506115e09060203d6020116115e6575b6115d8818361206d565b8101906122ae565b9261159a565b503d6115ce565b6040513d88823e3d90fd5b611611915060203d6020116115e6576115d8818361206d565b3861156b565b611630915060803d6080116110e1576110cf818361206d565b50505038611540565b6040513d86823e3d90fd5b9060a0906114a8565b50346109605780600319360112610960576040517f000000000000000000000000571291b572ed32ce6751a2cb2486ebee8defb9b46001600160a01b03168152602090f35b5034610960576020366003190112610960576116ac611f3b565b6001546001600160a01b031691906116c5338414612018565b6040516370a0823160e01b81523060048201526001600160a01b039190911692602082602481875afa9182156117ab578392611775575b5060405163a9059cbb60e01b81526001600160a01b0390911660048201526024810191909152916020908390818481604481015b03925af1908115611769575061174c575b602060405160018152f35b6117649060203d60201161073c5761072d818361206d565b611741565b604051903d90823e3d90fd5b91506020823d6020116117a3575b816117906020938361206d565b810103126107ef579051906117306116fc565b3d9150611783565b6040513d85823e3d90fd5b5034610960576040366003190112610960576117d0611f3b565b6024359160ff831683036109605760206111de8484612262565b50346109605760603660031901126109605760a0611806611f3b565b61180e611f51565b90611817611f67565b906000196001851b0183811690821610156118f657915b6040519261183b84612051565b600180861b03168352600180851b03166020830152628000006040830152603c6060830152600180841b031660808201522060405190633205590760e21b8252600482015260808160248160018060a01b037f000000000000000000000000571291b572ed32ce6751a2cb2486ebee8defb9b4165afa90811561137e57602092916118d4575b506040516001600160a01b039091168152f35b6118ed915060803d6080116110e1576110cf818361206d565b505050386118c1565b61182e565b50346109605760a036600319011261096057611915611f3b565b61191d611f51565b91611926612002565b906084359260018060a01b038416809403611b29576001600160a01b038581169082161015611b205760a0905b640100ad139c9473ff53611968f1e5ca45cfca7918447e7f5776f6d4966040519261197d84612051565b600180861b03168352600180851b03166020830152628000006040830152603c60608301526080820152209160405192633205590760e21b8452600484015260808360248160018060a01b037f000000000000000000000000571291b572ed32ce6751a2cb2486ebee8defb9b4165afa92831561137e578293611afc575b50604051631efeed3360e01b81526064356004820152906020826024817f0000000000000000000000004b2c77d209d3405f41a037ec6c77f7f5b8e2ca806001600160a01b03165afa9182156117ab578392611ab1575b506001600160801b03809116911602906001600160801b038216918203611a9d575092611a9191611a8b61271060409604809383612363565b93612182565b82519182526020820152f35b634e487b7160e01b81526011600452602490fd5b9091506020813d602011611af4575b81611acd6020938361206d565b8101031261084957516001600160801b038116810361084957906001600160801b03611a52565b3d9150611ac0565b611b1691935060803d6080116110e1576110cf818361206d565b50505091386119fb565b9360a090611953565b5080fd5b50346109605760603660031901126109605760206111de611b4c611f3b565b611b54611f51565b611b5c612002565b91612182565b50346109605760a036600319011261096057611b7c611f3b565b90611b85611f51565b611b8d611f67565b90611b96611f7d565b90608435946001600160801b038616809603611cfd5790611bb7929161208f565b80516040516020956001600160a01b03948516929094169190911492611bdd868361206d565b848252604051926080840184811067ffffffffffffffff821117611ce957926001600160801b0360409593611c6d93611c499688528552898501978852868501908152606085019283528651978896879663aa9d21cb60e01b88528c6004890152602488019051611fbf565b51151560c4860152511660e484015251610100610104840152610124830190612112565b0381857f0000000000000000000000004a6513c898fe1b2d0e78d3b0e0a4a151589b1cba6001600160a01b03165af1918215611769578092611cb4575b5050604051908152f35b9091506040823d604011611ce1575b81611cd06040938361206d565b810103126109605750513880611caa565b3d9150611cc3565b634e487b7160e01b87526041600452602487fd5b8480fd5b50346109605760603660031901126109605760a0611d36611d20611f3b565b611d28611f51565b611d30611f67565b9161208f565b611d436040518092611fbf565bf35b503461096057608036600319011261096057611d5f611f3b565b50611d68611f51565b5060643567ffffffffffffffff8111611b295736602382011215611b2957806004013567ffffffffffffffff8111610849573691016024011161096057604051630a85bd0160e11b8152602090f35b5034610960578060031936011261096057546040516001600160a01b039091168152602090f35b50346109605780600319360112610960576040517f000000000000000000000000492e6456d9528771018deb9e87ef7750ef1841046001600160a01b03168152602090f35b503461096057602036600319011261096057600435611e4d60018060a01b03600154163314612018565b7f0000000000000000000000004b2c77d209d3405f41a037ec6c77f7f5b8e2ca806001600160a01b031690813b156108495760405163095ea7b360e01b815230600482015260248101829052838160448183875af1801561163957611f27575b506001546001600160a01b031691839190803b1561084957604051632142170760e11b81523060048201526001600160a01b0394909416602485015260448401919091528290606490829084905af1801561137e57611f12575b602082604051908152f35b611f1d82809261206d565b6109605738611f07565b83611f349194929461206d565b9138611ead565b600435906001600160a01b03821682036107ef57565b602435906001600160a01b03821682036107ef57565b604435906001600160a01b03821682036107ef57565b606435906001600160a01b03821682036107ef57565b60c435906001600160a01b03821682036107ef57565b60e435906001600160a01b03821682036107ef57565b80516001600160a01b03908116835260208083015182169084015260408083015162ffffff169084015260608083015160020b9084015260809182015116910152565b604435906001600160801b03821682036107ef57565b1561201f57565b60405162461bcd60e51b815260206004820152600a60248201526927b7363c9027bbb732b960b11b6044820152606490fd5b60a0810190811067ffffffffffffffff82111761087457604052565b90601f8019910116810190811067ffffffffffffffff82111761087457604052565b919091600060806040516120a281612051565b82815260208101839052604081018390526060810183905201526001600160a01b03838116908216101561210d57915b604051926120df84612051565b6001600160a01b0390811684529081166020840152628000006040840152603c606084015216608082015290565b6120d2565b919082519283825260005b84811061213e575050826000602080949584010152601f8019910116010190565b8060208092840101518282860101520161211d565b6001600160a01b03918216908216039190821161216c57565b634e487b7160e01b600052601160045260246000fd5b6121bf92916001600160801b03916001600160a01b03808316908216116121c2575b6001600160a01b03916121b79190612153565b1691166125dc565b90565b906121a4565b519062ffffff821682036107ef57565b91908260809103126107ef5781516001600160a01b03811681036107ef579160208101518060020b81036107ef57916121bf6060612218604085016121c8565b93016121c8565b8181029291811591840414171561216c57565b6001600160a01b0316801561225c57670de0b6b3a76400006122576121bf928061221f565b612626565b50600090565b6001600160a01b031690811561228f5760ff1690604d821161216c576122576121bf92600a0a918061221f565b5050600090565b908160209103126107ef575180151581036107ef5790565b908160209103126107ef575160ff811681036107ef5790565b936001600160a01b038381169083161161235b575b6001600160a01b038581169590831686116122fd5750506121bf93506127ba565b919490939192906001600160a01b038216111561234f5782916123249161232a95946127ba565b93612780565b6001600160801b0381166001600160801b0383161060001461234a575090565b905090565b9150506121bf92612780565b9091906122dc565b916123ba916001600160a01b03808216908516116123e6575b6001600160a01b0361238e8583612153565b6001600160a01b039092169291169060601b6fffffffffffffffffffffffffffffffff60601b166126fd565b6001600160a01b039091169081156123d0570490565b634e487b7160e01b600052601260045260246000fd5b9261237c565b604051606091906123fd838261206d565b6002815291601f19018260005b82811061241657505050565b80606060208093850101520161240a565b8051156124345760200190565b634e487b7160e01b600052603260045260246000fd5b8051600110156124345760400190565b8051600210156124345760600190565b9080602083519182815201916020808360051b8301019401926000915b83831061249657505050505090565b90919293946020806124b4600193601f198682030187528951612112565b97019301930191939290612487565b90916124da6121bf93604084526040840190612112565b91602081840391015261246a565b9291906124ff602091604086526040860190612112565b930152565b604051631d5e528f60e21b81526020816004817f0000000000000000000000004b2c77d209d3405f41a037ec6c77f7f5b8e2ca806001600160a01b03165afa90811561258457600091612555575090565b90506020813d60201161257c575b816125706020938361206d565b810103126107ef575190565b3d9150612563565b6040513d6000823e3d90fd5b65ffffffffffff610e109116019065ffffffffffff821161216c57565b6001600160a01b0391821681529181166020830152604082015265ffffffffffff909116606082015260800190565b818102919060001982820991838084109303928084039384600160601b11156107ef571461261d57600160601b910990828211900360a01b910360601c1790565b50505060601c90565b818102919060001982820991838084109303928084039384600160c01b11156107ef571461266757600160c01b910990828211900360401b910360c01c1790565b50505060c01c90565b90606082901b90600019600160601b8409928280851094039380850394858411156107ef57146126f6578190600160601b9009818060000316809204600281600302188082026002030280820260020302808202600203028082026002030280820260020302809102600203029360018380600003040190848311900302920304170290565b5091500490565b9181830291600019818509938380861095039480860395868511156107ef57146127785790829109818060000316809204600281600302188082026002030280820260020302808202600203028082026002030280820260020302809102600203029360018380600003040190848311900302920304170290565b505091500490565b6121bf926127af9290916001600160a01b03808316908216116127b4575b90036001600160a01b031690612670565b612807565b9061279e565b6121bf926127af929091906001600160a01b0380821690831611612801575b6127ef6001600160a01b038281169084166125dc565b9190036001600160a01b0316916126fd565b906127d9565b906001600160801b03821680920361281b57565b60405162461bcd60e51b81526020600482015260096024820152681b9bdd08195c5d585b60ba1b6044820152606490fdfea264697066735822122045fe6b8813aecac364e4fab20dd37159ac9ca490df7b6be67a140c1c608232c864736f6c634300081c0033

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
0xc728AF6267315b5CB7669D7DC4F87f5174adabE8
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.