ETH Price: $3,058.63 (+2.57%)
Gas: 1 Gwei

Contract

0xDa40b7319bc6b1E668FAe6D013B34BF190Fd2860
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Value
Refund181713712023-09-19 17:13:47291 days ago1695143627IN
0xDa40b731...190Fd2860
0 ETH0.0019443519.99213774
Refund181547612023-09-17 9:05:23293 days ago1694941523IN
0xDa40b731...190Fd2860
0 ETH0.00080228.24840893
Refund181533102023-09-17 4:08:47293 days ago1694923727IN
0xDa40b731...190Fd2860
0 ETH0.00076227.83714564
Refund181527352023-09-17 2:11:23293 days ago1694916683IN
0xDa40b731...190Fd2860
0 ETH0.000808238.31043216
Refund181526152023-09-17 1:46:47293 days ago1694915207IN
0xDa40b731...190Fd2860
0 ETH0.000918769.44687119
Refund181524722023-09-17 1:16:23293 days ago1694913383IN
0xDa40b731...190Fd2860
0 ETH0.000880059.04880639
Refund181499622023-09-16 16:44:47294 days ago1694882687IN
0xDa40b731...190Fd2860
0 ETH0.0015695713.72537515

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To Value
181713712023-09-19 17:13:47291 days ago1695143627
0xDa40b731...190Fd2860
0.0891 ETH
181713712023-09-19 17:13:47291 days ago1695143627
0xDa40b731...190Fd2860
0.0891 ETH
181547612023-09-17 9:05:23293 days ago1694941523
0xDa40b731...190Fd2860
0.01782 ETH
181547612023-09-17 9:05:23293 days ago1694941523
0xDa40b731...190Fd2860
0.01782 ETH
181541322023-09-17 6:56:23293 days ago1694933783
0xDa40b731...190Fd2860
0.0099 ETH
181541322023-09-17 6:56:23293 days ago1694933783
0xDa40b731...190Fd2860
0.0099 ETH
181541292023-09-17 6:55:47293 days ago1694933747
0xDa40b731...190Fd2860
0.0099 ETH
181541292023-09-17 6:55:47293 days ago1694933747
0xDa40b731...190Fd2860
0.0099 ETH
181533102023-09-17 4:08:47293 days ago1694923727
0xDa40b731...190Fd2860
0.02673 ETH
181533102023-09-17 4:08:47293 days ago1694923727
0xDa40b731...190Fd2860
0.02673 ETH
181527352023-09-17 2:11:23293 days ago1694916683
0xDa40b731...190Fd2860
0.03564 ETH
181527352023-09-17 2:11:23293 days ago1694916683
0xDa40b731...190Fd2860
0.03564 ETH
181526152023-09-17 1:46:47293 days ago1694915207
0xDa40b731...190Fd2860
0.06237 ETH
181526152023-09-17 1:46:47293 days ago1694915207
0xDa40b731...190Fd2860
0.06237 ETH
181524722023-09-17 1:16:23293 days ago1694913383
0xDa40b731...190Fd2860
0.0891 ETH
181524722023-09-17 1:16:23293 days ago1694913383
0xDa40b731...190Fd2860
0.0891 ETH
181518962023-09-16 23:18:23294 days ago1694906303
0xDa40b731...190Fd2860
0.0198 ETH
181518962023-09-16 23:18:23294 days ago1694906303
0xDa40b731...190Fd2860
0.0198 ETH
181514802023-09-16 21:53:59294 days ago1694901239
0xDa40b731...190Fd2860
0.0297 ETH
181514802023-09-16 21:53:59294 days ago1694901239
0xDa40b731...190Fd2860
0.0297 ETH
181504022023-09-16 18:13:47294 days ago1694888027
0xDa40b731...190Fd2860
0.0297 ETH
181504022023-09-16 18:13:47294 days ago1694888027
0xDa40b731...190Fd2860
0.0297 ETH
181503912023-09-16 18:11:23294 days ago1694887883
0xDa40b731...190Fd2860
0.0297 ETH
181503912023-09-16 18:11:23294 days ago1694887883
0xDa40b731...190Fd2860
0.0297 ETH
181503282023-09-16 17:58:35294 days ago1694887115
0xDa40b731...190Fd2860
0.0099 ETH
View All Internal Transactions
Loading...
Loading

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

Contract Name:
InitialFairOffering

Compiler Version
v0.8.18+commit.87f61d96

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 12 : InitialFairOffering.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;

import "./interfaces/IInscription.sol";
import "./interfaces/IInscriptionFactory.sol";
import "./interfaces/INonfungiblePositionManager.sol";
import "./interfaces/IWETH.sol";
import "./libs/TransferHelper.sol";
import "./libs/PriceFormat.sol";
import "@uniswap/v3-core/contracts/interfaces/IUniswapV3Factory.sol";
import "./interfaces/ICustomizedVesting.sol";

// This contract will be created while deploying
// The liquidity can not be removed
contract InitialFairOffering {
    int24 private constant MIN_TICK = -887272; // add liquidity with full range
    int24 private constant MAX_TICK = -MIN_TICK; // add liquidity with full range
    int24 public constant TICK_SPACING = 60; // Tick space is 60
    uint24 public constant UNISWAP_FEE = 3000;

    INonfungiblePositionManager public constant nonfungiblePositionManager =
        INonfungiblePositionManager(0xC36442b4a4522E871399CD717aBDD847Ab11FE88);

    IUniswapV3Factory public uniswapV3Factory =
        IUniswapV3Factory(0x1F98431c8aD98523631AE4a59f267346ea31F984);

    IWETH public weth;

    IInscriptionFactory public inscriptionFactory;

    bool public liquidityAdded = false;

    struct MintData {
        uint128 ethAmount; // eth payed by user(deduce commission)
        uint128 tokenAmount; // token minted by user
        uint128 tokenLiquidity; // token liquidity saved in this contract
    }

    mapping(address => MintData) public mintData;

    struct Deposit {
        address owner;
        uint128 liquidity;
        address token0;
        address token1;
    }
    mapping(uint => Deposit) public deposits; // uint - tokenId of liquidity NFT
    mapping(uint => uint) public tokenIds;
    uint public tokenIdCount;
    uint public totalBackToDeployAmount;
    uint public totalRefundedAmount;

    struct Position {
        uint96 nonce;
        address operator;
        address token0;
        address token1;
        uint24 fee;
        int24 tickLower;
        int24 tickUpper;
        uint128 liquidity;
        uint256 feeGrowthInside0LastX128;
        uint256 feeGrowthInside1LastX128;
        uint128 tokensOwed0;
        uint128 tokensOwed1;
        uint256 tokenId;
    }

    struct Pool {
        address pool;
        address token0;
        address token1;
        uint uintRate;
        uint160 sqrtPriceX96;
    }
    Pool public poolData;

    IInscriptionFactory.Token public token;

    event MintDeposit(
        address token,
        uint128 ethAmount,
        uint128 tokenAmount,
        uint128 tokenLiquidity
    );
    event Refund(
        address sender,
        uint128 etherAmount,
        uint128 senderToken,
        uint128 liquidityToken,
        uint16 refundFee
    );

    // This contract can be only created by InscriptionFactory contract
    constructor(address _inscriptionFactory, address _weth) {
        inscriptionFactory = IInscriptionFactory(_inscriptionFactory);
        weth = IWETH(_weth);
    }

    receive() external payable {
        // Change all received ETH to WETH
        if (msg.sender != address(weth))
            TransferHelper.safeTransferETH(address(weth), msg.value);
    }

    function initialize(IInscriptionFactory.Token memory _token) public {
        // Check if the deployer has sent the liquidity ferc20 tokens
        require(
            address(inscriptionFactory) == msg.sender,
            "Only inscription factory allowed"
        );
        require(_token.inscriptionId > 0, "token data wrong");
        token = _token;
        _initializePool(address(weth), _token.addr);
    }

    function _initializePool(
        address _weth,
        address _token
    )
        private
        returns (
            address _token0,
            address _token1,
            uint _uintRate,
            uint160 _sqrtPriceX96,
            address _pool
        )
    {
        _token0 = _token;
        _token1 = _weth;

        _uintRate = PriceFormat.getInitialRate(
            token.crowdFundingRate,
            token.liquidityEtherPercent,
            token.liquidityTokenPercent,
            token.limitPerMint
        ); // weth quantity per token
        require(_uintRate > 0, "uint rate zero");

        if (_token < _weth) {
            _sqrtPriceX96 = PriceFormat.priceToSqrtPriceX96(
                int(_uintRate),
                TICK_SPACING
            );
        } else {
            _token0 = _weth;
            _token1 = _token;
            _uintRate = 10 ** 36 / _uintRate; // token quantity per weth
            _sqrtPriceX96 = PriceFormat.priceToSqrtPriceX96(
                int(_uintRate),
                TICK_SPACING
            );
        }
        _pool = nonfungiblePositionManager.createAndInitializePoolIfNecessary(
            _token0,
            _token1,
            UNISWAP_FEE,
            _sqrtPriceX96
        );
        poolData = Pool(_pool, _token0, _token1, _uintRate, _sqrtPriceX96);
    }

    function addLiquidity(uint16 slippage) public {
        require(slippage >= 0 && slippage <= 10000, "slippage error");
        require(
            IInscription(token.addr).totalRollups() >= token.maxRollups,
            "mint not finished"
        );
        require(
            uniswapV3Factory.getPool(address(weth), token.addr, UNISWAP_FEE) >
                address(0x0),
            "Pool not exist, create pool in uniswapV3 manually"
        );
        require(token.liquidityEtherPercent > 0, "no liquidity add");
        uint256 totalTokenLiquidity = IInscription(token.addr).balanceOf(
            address(this)
        );
        require(totalTokenLiquidity > 0, "no token in fto contract");
        uint256 balanceOfWeth = IWETH(weth).balanceOf(address(this));
        require(balanceOfWeth > 0, "no eth in fto contract");

        // Send ether back to deployer, the eth liquidity is based on the balance of this contract. So, anyone can send eth to this contract
        uint256 backToDeployAmount = (balanceOfWeth *
            (10000 - token.liquidityEtherPercent)) / 10000;
        uint256 maxBackToDeployAmount = (token.maxRollups *
            (10000 - inscriptionFactory.fundingCommission()) *
            token.crowdFundingRate *
            (10000 - token.liquidityEtherPercent)) / 100000000;

        uint256 sum = totalBackToDeployAmount + backToDeployAmount;

        if (sum <= maxBackToDeployAmount) {
            weth.withdraw(backToDeployAmount); // Change WETH to ETH
            TransferHelper.safeTransferETH(token.deployer, backToDeployAmount);
            totalBackToDeployAmount += backToDeployAmount;
        } else {
            backToDeployAmount = 0;
        }

        liquidityAdded = true; // allow the transferring of token

        _mintNewPosition(
            balanceOfWeth - backToDeployAmount,
            totalTokenLiquidity, // ferc20 token amount
            MIN_TICK,
            MAX_TICK,
            slippage
        );
    }

    function refund() public {
        require(mintData[msg.sender].ethAmount > 0, "you have not mint");
        require(
            IInscription(token.addr).totalRollups() < token.maxRollups,
            "mint has finished"
        );

        if (
            token.isVesting &&
            token.customizedVestingContractAddress != address(0x0)
        ) {
            // standard fto mode
            ICustomizedVesting(token.customizedVestingContractAddress)
                .removeAllocation(msg.sender, mintData[msg.sender].tokenAmount);
        } else {
            // not fto mode
            // check balance and allowance of tokens, if the balance or allowance is smaller than the what he/she get while do mint, the refund fail
            require(
                IInscription(token.addr).balanceOf(msg.sender) >=
                    mintData[msg.sender].tokenAmount,
                "Your balance token not enough"
            );
            require(
                IInscription(token.addr).allowance(msg.sender, address(this)) >=
                    mintData[msg.sender].tokenAmount,
                "Your allowance not enough"
            );

            // Burn the tokens from msg.sender
            IInscription(token.addr).burnFrom(
                msg.sender,
                mintData[msg.sender].tokenAmount
            );
        }

        // Burn the token liquidity in this contract
        uint128 refundToken = (mintData[msg.sender].tokenLiquidity *
            token.refundFee) / 10000;
        IInscription(token.addr).burn(
            address(this),
            mintData[msg.sender].tokenLiquidity - refundToken
        );

        // Refund Ether
        uint128 refundEth = (mintData[msg.sender].ethAmount * token.refundFee) /
            10000;
        weth.withdraw(mintData[msg.sender].ethAmount - refundEth); // Change WETH to ETH
        TransferHelper.safeTransferETH(
            msg.sender,
            mintData[msg.sender].ethAmount - refundEth
        ); // Send balance to donator

        totalRefundedAmount =
            totalRefundedAmount +
            mintData[msg.sender].tokenAmount +
            mintData[msg.sender].tokenLiquidity -
            refundToken;

        emit Refund(
            msg.sender,
            mintData[msg.sender].ethAmount - refundEth,
            mintData[msg.sender].tokenAmount,
            mintData[msg.sender].tokenLiquidity - refundToken,
            token.refundFee
        );

        mintData[msg.sender].tokenAmount = 0;
        mintData[msg.sender].tokenLiquidity = 0;
        mintData[msg.sender].ethAmount = 0;
    }

    function positions(
        uint128 pageNo,
        uint128 pageSize
    ) public view returns (Position[] memory _positions) {
        require(pageNo > 0 && pageSize > 0, "pageNo and size can not be zero");
        Position[] memory filtered = new Position[](tokenIdCount);
        uint128 count = 0;
        for (uint128 i = 0; i < tokenIdCount; i++) {
            (
                uint96 nonce,
                address operator,
                address token0,
                address token1,
                uint24 fee,
                int24 tickLower,
                int24 tickUpper,
                uint128 liquidity,
                uint256 feeGrowthInside0LastX128,
                uint256 feeGrowthInside1LastX128,
                uint128 tokensOwed0,
                uint128 tokensOwed1
            ) = nonfungiblePositionManager.positions(tokenIds[i]);
            if (liquidity == 0) continue;
            filtered[count] = Position(
                nonce,
                operator,
                token0,
                token1,
                fee,
                tickLower,
                tickUpper,
                liquidity,
                feeGrowthInside0LastX128,
                feeGrowthInside1LastX128,
                tokensOwed0,
                tokensOwed1,
                tokenIds[i]
            );
            count++;
        }

        uint128 startIndex = (pageNo - 1) * pageSize;
        if (startIndex > count) return new Position[](0);

        _positions = new Position[](pageSize);
        uint128 index;
        for (uint128 i = 0; i < filtered.length; i++) {
            if (i >= startIndex && i < startIndex + pageSize) {
                _positions[index] = filtered[i];
                index++;
            } else continue;
        }
    }

    // Call from Inscription::mint only
    function setMintData(
        address _addr,
        uint128 _ethAmount,
        uint128 _tokenAmount,
        uint128 _tokenLiquidity
    ) public {
        require(msg.sender == token.addr, "Only call from inscription allowed");
        require(
            _ethAmount > 0 &&
                _tokenAmount > 0 &&
                _tokenLiquidity > 0 &&
                _addr > address(0x0),
            "setEtherLiquidity wrong params"
        );

        mintData[_addr].ethAmount = mintData[_addr].ethAmount + _ethAmount;
        mintData[_addr].tokenAmount =
            mintData[_addr].tokenAmount +
            _tokenAmount;
        mintData[_addr].tokenLiquidity =
            mintData[_addr].tokenLiquidity +
            _tokenLiquidity;

        emit MintDeposit(msg.sender, _ethAmount, _tokenAmount, _tokenLiquidity);
    }

    function collectFee(
        uint256 _tokenId
    ) public returns (uint256 amount0, uint256 amount1) {
        // Collect
        INonfungiblePositionManager.CollectParams
            memory params = INonfungiblePositionManager.CollectParams({
                tokenId: _tokenId,
                recipient: address(this),
                amount0Max: type(uint128).max,
                amount1Max: type(uint128).max
            });
        (amount0, amount1) = nonfungiblePositionManager.collect(params);
    }

    function _mintNewPosition(
        uint amount0ToAdd,
        uint amount1ToAdd,
        int24 lowerTick,
        int24 upperTick,
        uint16 slippage
    )
        private
        returns (uint tokenId, uint128 liquidity, uint amount0, uint amount1)
    {
        // If weth < ferc20, set token0/amount0 is weth and token1/amount1 is ferc20
        // Otherwise, set token0/amount0 is ferc20, and token1/amount1 is weth
        address _token0;
        address _token1;
        uint _amount0;
        uint _amount1;
        int24 _lowerTick;
        int24 _upperTick;
        if (address(weth) > token.addr) {
            _token0 = token.addr;
            _token1 = address(weth);
            _amount0 = amount1ToAdd;
            _amount1 = amount0ToAdd;
            _lowerTick = lowerTick;
            _upperTick = upperTick;
        } else {
            _token0 = address(weth);
            _token1 = token.addr;
            _amount0 = amount0ToAdd;
            _amount1 = amount1ToAdd;
            _lowerTick = -upperTick;
            _upperTick = -lowerTick;
        }

        // Approve the position manager
        TransferHelper.safeApprove(
            _token0,
            address(nonfungiblePositionManager),
            _amount0
        );
        TransferHelper.safeApprove(
            _token1,
            address(nonfungiblePositionManager),
            _amount1
        );

        INonfungiblePositionManager.MintParams memory params = INonfungiblePositionManager
            .MintParams({
                token0: _token0,
                token1: _token1,
                fee: UNISWAP_FEE,
                tickLower: (lowerTick / TICK_SPACING) * TICK_SPACING, // full range
                tickUpper: (upperTick / TICK_SPACING) * TICK_SPACING,
                amount0Desired: _amount0,
                amount1Desired: _amount1,
                amount0Min: (_amount0 * (10000 - slippage)) / 10000, // slipage
                amount1Min: (_amount1 * (10000 - slippage)) / 10000,
                recipient: address(this),
                deadline: block.timestamp
            });

        (tokenId, liquidity, amount0, amount1) = nonfungiblePositionManager
            .mint(params);

        _createDeposit(msg.sender, tokenId);

        if (amount0 < _amount0) {
            TransferHelper.safeApprove(
                _token0,
                address(nonfungiblePositionManager),
                0
            );
        }

        if (amount1 < _amount1) {
            TransferHelper.safeApprove(
                _token1,
                address(nonfungiblePositionManager),
                0
            );
        }
    }

    function _createDeposit(address _operator, uint _tokenId) private {
        (
            ,
            ,
            address token0,
            address token1,
            ,
            ,
            ,
            uint128 liquidity,
            ,
            ,
            ,

        ) = nonfungiblePositionManager.positions(_tokenId);

        if (deposits[_tokenId].owner == address(0x0)) {
            tokenIds[tokenIdCount] = _tokenId;
            tokenIdCount++;
        }

        deposits[_tokenId] = Deposit({
            owner: _operator,
            liquidity: liquidity,
            token0: token0,
            token1: token1
        });
    }

    // function onERC721Received(
    //     address operator,
    //     address from,
    //     uint tokenId,
    //     bytes calldata
    // ) public returns (bytes4) {
    //     _createDeposit(operator, tokenId);
    //     return IERC721Receiver.onERC721Received.selector;
    // }

    // Add liquidity with lower/upper tick
    // function addLiquidity(
    //     uint16 ratio,            // The ratio of balance of eths and tokens will be added to liquidity pool
    //     int24 lowerTick,
    //     int24 upperTick,
    //     uint16 slippage
    // ) public {
    //     require(ratio > 0 && ratio <= 10000, "ratio error");
    //     require(slippage >= 0 && slippage <= 10000, "slippage error");
    //     require(IInscription(token.addr).balanceOf(msg.sender) >= token.minBalanceToManagerLiquidity, "Balance not enough to add liquidity");
    //     require(IInscription(token.addr).totalRollups() >= token.maxRollups, "mint not finished");
    //     require(uniswapV3Factory.getPool(address(weth), token.addr, UNISWAP_FEE) > address(0x0), "Pool not exist, create pool in uniswapV3 manually");
    //     require(token.liquidityEtherPercent > 0, "no liquidity add");
    //     uint256 totalTokenLiquidity = IInscription(token.addr).balanceOf(address(this));
    //     require(totalTokenLiquidity > 0, "no token in fto");
    //     uint256 balanceOfWeth = IWETH(weth).balanceOf(address(this));
    //     require(balanceOfWeth > 0, "no eth in fto");

    //     // Send ether back to deployer, the eth liquidity is based on the balance of this contract. So, anyone can send eth to this contract
    //     uint256 backToDeployAmount = balanceOfWeth * (10000 - token.liquidityEtherPercent) * ratio / 100000000;
    //     uint256 maxBackToDeployAmount = token.maxRollups * (10000 - inscriptionFactory.fundingCommission()) * token.crowdFundingRate * (10000 - token.liquidityEtherPercent) / 100000000;

    //     uint256 sum = totalBackToDeployAmount + backToDeployAmount;

    //     if(sum <= maxBackToDeployAmount) {
    //         weth.withdraw(backToDeployAmount);  // Change WETH to ETH
    //         TransferHelper.safeTransferETH(token.deployer, backToDeployAmount);
    //         totalBackToDeployAmount += backToDeployAmount;
    //     } else {
    //         backToDeployAmount = 0;
    //     }

    //     _mintNewPosition(
    //         balanceOfWeth * ratio / 10000 - backToDeployAmount,
    //         totalTokenLiquidity * ratio / 10000,  // ferc20 token amount
    //         lowerTick == 0 ? MIN_TICK : lowerTick,
    //         upperTick == 0 ? MAX_TICK : upperTick,
    //         slippage
    //     );
    // }

    // function decreaseLiquidity(
    //     uint tokenId
    // ) public returns (uint amount0, uint amount1) {
    //     require(IInscription(token.addr).totalRollups() >= token.maxRollups, "mint not finished");
    //     require(IInscription(token.addr).balanceOf(msg.sender) >= token.minBalanceToManagerLiquidity, "Balance not enough to decrease liquidity");
    //     uint128 decreaseLiquidityAmount = deposits[tokenId].liquidity;

    //     INonfungiblePositionManager.DecreaseLiquidityParams memory params = INonfungiblePositionManager.DecreaseLiquidityParams({
    //         tokenId: tokenId,
    //         liquidity: decreaseLiquidityAmount,
    //         amount0Min: 0,
    //         amount1Min: 0,
    //         deadline: block.timestamp
    //     });

    //     (amount0, amount1) = nonfungiblePositionManager.decreaseLiquidity(params);

    //     // Collect
    //     INonfungiblePositionManager.CollectParams memory params2 = INonfungiblePositionManager.CollectParams({
    //         tokenId: tokenId,
    //         recipient: address(this),
    //         amount0Max: type(uint128).max,
    //         amount1Max: type(uint128).max
    //     });

    //     (amount0, amount1) = nonfungiblePositionManager.collect(params2);

    //     deposits[tokenId].liquidity = 0;
    // }

    // function setMinBalanceToManagerLiquidity(uint128 _minBalanceToManagerLiquidity) public {
    //     require(msg.sender == token.deployer, "Call must be deployer");
    //     token.minBalanceToManagerLiquidity = _minBalanceToManagerLiquidity;
    // }
}

File 2 of 12 : IUniswapV3Factory.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.5.0;

/// @title The interface for the Uniswap V3 Factory
/// @notice The Uniswap V3 Factory facilitates creation of Uniswap V3 pools and control over the protocol fees
interface IUniswapV3Factory {
    /// @notice Emitted when the owner of the factory is changed
    /// @param oldOwner The owner before the owner was changed
    /// @param newOwner The owner after the owner was changed
    event OwnerChanged(address indexed oldOwner, address indexed newOwner);

    /// @notice Emitted when a pool is created
    /// @param token0 The first token of the pool by address sort order
    /// @param token1 The second token of the pool by address sort order
    /// @param fee The fee collected upon every swap in the pool, denominated in hundredths of a bip
    /// @param tickSpacing The minimum number of ticks between initialized ticks
    /// @param pool The address of the created pool
    event PoolCreated(
        address indexed token0,
        address indexed token1,
        uint24 indexed fee,
        int24 tickSpacing,
        address pool
    );

    /// @notice Emitted when a new fee amount is enabled for pool creation via the factory
    /// @param fee The enabled fee, denominated in hundredths of a bip
    /// @param tickSpacing The minimum number of ticks between initialized ticks for pools created with the given fee
    event FeeAmountEnabled(uint24 indexed fee, int24 indexed tickSpacing);

    /// @notice Returns the current owner of the factory
    /// @dev Can be changed by the current owner via setOwner
    /// @return The address of the factory owner
    function owner() external view returns (address);

    /// @notice Returns the tick spacing for a given fee amount, if enabled, or 0 if not enabled
    /// @dev A fee amount can never be removed, so this value should be hard coded or cached in the calling context
    /// @param fee The enabled fee, denominated in hundredths of a bip. Returns 0 in case of unenabled fee
    /// @return The tick spacing
    function feeAmountTickSpacing(uint24 fee) external view returns (int24);

    /// @notice Returns the pool address for a given pair of tokens and a fee, or address 0 if it does not exist
    /// @dev tokenA and tokenB may be passed in either token0/token1 or token1/token0 order
    /// @param tokenA The contract address of either token0 or token1
    /// @param tokenB The contract address of the other token
    /// @param fee The fee collected upon every swap in the pool, denominated in hundredths of a bip
    /// @return pool The pool address
    function getPool(
        address tokenA,
        address tokenB,
        uint24 fee
    ) external view returns (address pool);

    /// @notice Creates a pool for the given two tokens and fee
    /// @param tokenA One of the two tokens in the desired pool
    /// @param tokenB The other of the two tokens in the desired pool
    /// @param fee The desired fee for the pool
    /// @dev tokenA and tokenB may be passed in either order: token0/token1 or token1/token0. tickSpacing is retrieved
    /// from the fee. The call will revert if the pool already exists, the fee is invalid, or the token arguments
    /// are invalid.
    /// @return pool The address of the newly created pool
    function createPool(
        address tokenA,
        address tokenB,
        uint24 fee
    ) external returns (address pool);

    /// @notice Updates the owner of the factory
    /// @dev Must be called by the current owner
    /// @param _owner The new owner of the factory
    function setOwner(address _owner) external;

    /// @notice Enables a fee amount with the given tickSpacing
    /// @dev Fee amounts may never be removed once enabled
    /// @param fee The fee amount to enable, denominated in hundredths of a bip (i.e. 1e-6)
    /// @param tickSpacing The spacing between ticks to be enforced for all pools created with the given fee amount
    function enableFeeAmount(uint24 fee, int24 tickSpacing) external;
}

File 3 of 12 : ICustomizedCondition.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface ICustomizedCondition {
    function getStatus(address _tokenAddress, address _sender) external view returns(bool);
}

File 4 of 12 : ICustomizedVesting.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface ICustomizedVesting {
    function addAllocation(address recipient, uint amount) external;
    function removeAllocation(address recipient, uint amount) external;
    function claim() external;
    function available(address address_) external view returns (uint);
    function released(address address_) external view returns (uint);
    function outstanding(address address_) external view returns (uint);
    function setTokenAddress(address _tokenAddress) external;
}

File 5 of 12 : IInscription.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./ICustomizedCondition.sol";
import "./ICustomizedVesting.sol";

interface IInscription {
    struct FERC20 {
        uint128 cap;                                            // Max amount
        uint128 limitPerMint;                                   // Limitaion of each mint

        address onlyContractAddress;                            // Only addresses that hold these assets can mint
        uint32  maxMintSize;                                    // max mint size, that means the max mint quantity is: maxMintSize * limitPerMint
        uint64  inscriptionId;                                  // Inscription Id
        
        uint128 onlyMinQuantity;                                // Only addresses that the quantity of assets hold more than this amount can mint
        uint128 crowdFundingRate;                               // rate of crowdfunding

        address whitelist;                                      // whitelist contract
        uint40  freezeTime;                                     // The frozen time (interval) between two mints is a fixed number of seconds. You can mint, but you will need to pay an additional mint fee, and this fee will be double for each mint.
        uint16  fundingCommission;                              // commission rate of fund raising, 1000 means 10%
        uint16  liquidityTokenPercent;
        bool    isIFOMode;                                      // receiving fee of crowdfunding

        address payable inscriptionFactory;                     // Inscription factory contract address
        uint128 baseFee;                                        // base fee of the second mint after frozen interval. The first mint after frozen time is free.

        address payable ifoContractAddress;                     // Initial fair offering contract
        uint96  maxRollups;                                     // Max rollups

        ICustomizedCondition customizedConditionContractAddress;// Customized condition for mint
        ICustomizedVesting customizedVestingContractAddress;    // Customized vesting contract
    }

    function mint(address _to) payable external;
    function getFerc20Data() external view returns(FERC20 memory);
    function balanceOf(address owner) external view returns(uint256);
    function totalSupply() external view returns(uint256);
    function allowance(address owner, address spender) external view returns(uint256);
    function totalRollups() external view returns(uint256);
    function burn(address account, uint256 amount) external;
    function burnFrom(address account, uint256 amount) external;
}

File 6 of 12 : IInscriptionFactory.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IInscriptionFactory {
    struct Token {
        uint128         cap;                                // Hard cap of token
        uint128         limitPerMint;                       // Limitation per mint

        address         onlyContractAddress;
        uint32          maxMintSize;                        // max mint size, that means the max mint quantity is: maxMintSize * limitPerMint
        uint64          inscriptionId;                      // Inscription id

        uint128         onlyMinQuantity;
        uint128         crowdFundingRate;
				
        address         addr;                               // Contract address of inscribed token
        uint40          freezeTime;
        uint40          timestamp;                          // Inscribe timestamp
        uint16          liquidityTokenPercent;              // 10000 is 100%

        address         ifoContractAddress;                 // Initial fair offerting contract
        uint16          refundFee;                          // To avoid the refund attack, deploy sets this fee rate
        uint40          startTime;
        uint40          duration;

        address         customizedConditionContractAddress; // Customized condition for mint
        uint96          maxRollups;                         // max rollups

        address         deployer;                           // Deployer
        string          tick;                               // same as symbol in ERC20, max 5 chars, 10 bytes(80)
        uint16          liquidityEtherPercent;
        
        string          name;                               // full name of token, max 16 chars, 32 bytes(256)

        address         customizedVestingContractAddress;   // Customized contract for token vesting
        bool            isIFOMode;                          // is ifo mode
        bool            isWhitelist;                        // is whitelst condition
        bool            isVesting;
        bool            isVoted;
        
        string          logoUrl;                            // logo url, ifpfs cid, 64 chars, 128 bytes, 4 slots, ex.QmPK1s3pNYLi9ERiq3BDxKa4XosgWwFRQUydHUtz4YgpqB
    }

    function deploy(
        string memory _name,
        string memory _tick,
        uint256 _cap,
        uint256 _limitPerMint,
        uint256 _maxMintSize, // The max lots of each mint
        uint256 _freezeTime, // Freeze seconds between two mint, during this freezing period, the mint fee will be increased
        address _onlyContractAddress, // Only the holder of this asset can mint, optional
        uint256 _onlyMinQuantity, // The min quantity of asset for mint, optional
        uint256 _crowdFundingRate,
        address _crowdFundingAddress
    ) external returns (address _inscriptionAddress);

    function updateStockTick(string memory _tick, bool _status) external;

    function transferOwnership(address newOwner) external;

    function getIncriptionIdByAddress(address _addr) external view returns(uint256);

    function getIncriptionByAddress(address _addr) external view returns(Token memory tokens, uint256 totalSupplies, uint256 totalRollups);

    function fundingCommission() external view returns(uint16);

    function isExisting(string memory _tick) external view returns(bool);

    function isLiquidityAdded(address _addr) external view returns(bool);

}

File 7 of 12 : INonfungiblePositionManager.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface INonfungiblePositionManager {
    struct MintParams {
        address token0;
        address token1;
        uint24 fee;
        int24 tickLower;
        int24 tickUpper;
        uint amount0Desired;
        uint amount1Desired;
        uint amount0Min;
        uint amount1Min;
        address recipient;
        uint deadline;
    }

    function mint(
        MintParams calldata params
    )
        external
        payable
        returns (uint tokenId, uint128 liquidity, uint amount0, uint amount1);

    struct IncreaseLiquidityParams {
        uint tokenId;
        uint amount0Desired;
        uint amount1Desired;
        uint amount0Min;
        uint amount1Min;
        uint deadline;
    }

    function increaseLiquidity(
        IncreaseLiquidityParams calldata params
    ) external payable returns (uint128 liquidity, uint amount0, uint amount1);

    struct DecreaseLiquidityParams {
        uint tokenId;
        uint128 liquidity;
        uint amount0Min;
        uint amount1Min;
        uint deadline;
    }

    function decreaseLiquidity(
        DecreaseLiquidityParams calldata params
    ) external payable returns (uint amount0, uint amount1);

    struct CollectParams {
        uint tokenId;
        address recipient;
        uint128 amount0Max;
        uint128 amount1Max;
    }

    function collect(
        CollectParams calldata params
    ) external payable returns (uint amount0, uint amount1);

    function positions(
        uint256 tokenId
    ) external view returns (
        uint96 nonce,
        address operator,
        address token0,
        address token1,
        uint24 fee,
        int24 tickLower,
        int24 tickUpper,
        uint128 liquidity,
        uint256 feeGrowthInside0LastX128,
        uint256 feeGrowthInside1LastX128,
        uint128 tokensOwed0,
        uint128 tokensOwed1
    );

    function createAndInitializePoolIfNecessary(
        address token0,
        address token1,
        uint24 fee,
        uint160 sqrtPriceX96
    ) external returns (address pool);
}

File 8 of 12 : IWETH.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
// import "./IERC20.sol";

interface IWETH {
    function transfer(address recipient, uint amount) external returns (bool);
    function balanceOf(address account) external view returns (uint);
    function totalSupply() external view returns(uint);
    function deposit() external payable;
    function withdraw(uint amount) external;
}

File 9 of 12 : Logarithm.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

library Logarithm {
    /// @notice Finds the zero-based index of the first one in the binary representation of x.
    /// @dev See the note on msb in the "Find First Set" Wikipedia article https://en.wikipedia.org/wiki/Find_first_set
    /// @param x The uint256 number for which to find the index of the most significant bit.
    /// @return msb The index of the most significant bit as an uint256.
    function mostSignificantBit(uint256 x) public pure returns (uint256 msb) {
        if (x >= 2**128) {
            x >>= 128;
            msb += 128;
        }
        if (x >= 2**64) {
            x >>= 64;
            msb += 64;
        }
        if (x >= 2**32) {
            x >>= 32;
            msb += 32;
        }
        if (x >= 2**16) {
            x >>= 16;
            msb += 16;
        }
        if (x >= 2**8) {
            x >>= 8;
            msb += 8;
        }
        if (x >= 2**4) {
            x >>= 4;
            msb += 4;
        }
        if (x >= 2**2) {
            x >>= 2;
            msb += 2;
        }
        if (x >= 2**1) {
            // No need to shift x any more.
            msb += 1;
        }
    }
    /// @notice Calculates the binary logarithm of x.
    ///
    /// @dev Based on the iterative approximation algorithm.
    /// https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation
    ///
    /// Requirements:
    /// - x must be greater than zero.
    ///
    /// Caveats:
    /// - The results are nor perfectly accurate to the last digit, due to the lossy precision of the iterative approximation.
    ///
    /// @param x The signed 59.18-decimal fixed-point number for which to calculate the binary logarithm.
    /// @return result The binary logarithm as a signed 59.18-decimal fixed-point number.
    function log2(int256 x, int256 scale, int256 halfScale) public pure returns (int256 result) {
        require(x > 0);
        unchecked {
            // This works because log2(x) = -log2(1/x).
            int256 sign;
            if (x >= scale) {
                sign = 1;
            } else {
                sign = -1;
                // Do the fixed-point inversion inline to save gas. The numerator is SCALE * SCALE.
                assembly {
                    x := div(1000000000000000000000000000000000000, x)
                }
            }

            // Calculate the integer part of the logarithm and add it to the result and finally calculate y = x * 2^(-n).
            uint256 n = mostSignificantBit(uint256(x / scale));

            // The integer part of the logarithm as a signed 59.18-decimal fixed-point number. The operation can't overflow
            // because n is maximum 255, SCALE is 1e18 and sign is either 1 or -1.
            result = int256(n) * scale;

            // This is y = x * 2^(-n).
            int256 y = x >> n;

            // If y = 1, the fractional part is zero.
            if (y == scale) {
                return result * sign;
            }

            // Calculate the fractional part via the iterative approximation.
            // The "delta >>= 1" part is equivalent to "delta /= 2", but shifting bits is faster.
            for (int256 delta = int256(halfScale); delta > 0; delta >>= 1) {
                y = (y * y) / scale;

                // Is y^2 > 2 and so in the range [2,4)?
                if (y >= 2 * scale) {
                    // Add the 2^(-m) factor to the logarithm.
                    result += delta;

                    // Corresponds to z/2 on Wikipedia.
                    y >>= 1;
                }
            }
            result *= sign;
        }
    }
}

File 10 of 12 : PriceFormat.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.5.0 <0.9.0;

import "./TickMath.sol";
import "./Logarithm.sol";

library PriceFormat {
    function getInitialRate(
        uint128 _crowdFundingRate,
        uint16  _etherToLiquidityPercent,
        uint16  _tokenToLiquidityPercent,
        uint128 _limitPerMint
    ) internal pure returns(uint) {
        // return _crowdFundingRate * _etherToLiquidityPercent * (10000 - _tokenToLiquidityPercent) * 10**14 / _tokenToLiquidityPercent / _limitPerMint;
        // To avoid the result is zero, the params must satisfy the following condition:
        // _crowdFundingRate * 10**18 > _limitPerMint
        uint128 precision = 10**12;
        return (_crowdFundingRate / precision) * _etherToLiquidityPercent * (10000 - _tokenToLiquidityPercent) * 10**14 / _tokenToLiquidityPercent / (_limitPerMint / precision);
    }

    function tickToSqrtPriceX96(int24 _tick) internal pure returns(uint160) {
        return TickMath.getSqrtRatioAtTick(_tick);
    }

    function priceToTick(int256 _price, int24 _tickSpace) internal pure returns(int24) {
        // math.log(10**18,2) * 10**18 = 59794705707972520000
        // math.log(1.0001,2) * 10**18 = 144262291094538
        return round((Logarithm.log2(_price * 1e18, 1e18, 5e17) - 59794705707972520000 ), (int(144262291094538) * _tickSpace)) * _tickSpace;
    }

    function priceToSqrtPriceX96(int256 _price, int24 _tickSpace) internal pure returns(uint160) {
        return tickToSqrtPriceX96(priceToTick(_price, _tickSpace));
    }

    function round(int256 _a, int256 _b) internal pure returns(int24) {
        return int24(10000 * _a / _b % 10000 > 10000 / 2 ? _a / _b + 1 : _a / _b);
    }
}

File 11 of 12 : TickMath.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.5.0 <0.9.0;

/// @title Math library for computing sqrt prices from ticks and vice versa
/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports
/// prices between 2**-128 and 2**128
library TickMath {
    /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128
    int24 internal constant MIN_TICK = -887272;
    /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128
    int24 internal constant MAX_TICK = -MIN_TICK;

    /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)
    uint160 internal constant MIN_SQRT_RATIO = 4295128739;
    /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)
    uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;

    /// @notice Calculates sqrt(1.0001^tick) * 2^96
    /// @dev Throws if |tick| > max tick
    /// @param tick The input tick for the above formula
    /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)
    /// at the given tick
    function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {
        // uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));
        int256 absTick = tick < 0 ? int256(-int256(tick)) : int256(int256(tick));
        require(absTick <= int256(MAX_TICK), 'T');

        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 Q128.96.
        // we then downcast because we know the result always fits within 160 bits due to our tick input constraint
        // we round up in the division so getTickAtSqrtRatio of the output price is always consistent
        sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));
    }

    /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio
    /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may
    /// ever return.
    /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96
    /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio
    function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {
        // second inequality must be < because the price can never reach the price at the max tick
        require(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO, 'R');
        uint256 ratio = uint256(sqrtPriceX96) << 32;

        uint256 r = ratio;
        uint256 msb = 0;

        assembly {
            let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))
            msb := or(msb, f)
            r := shr(f, r)
        }
        assembly {
            let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))
            msb := or(msb, f)
            r := shr(f, r)
        }
        assembly {
            let f := shl(5, gt(r, 0xFFFFFFFF))
            msb := or(msb, f)
            r := shr(f, r)
        }
        assembly {
            let f := shl(4, gt(r, 0xFFFF))
            msb := or(msb, f)
            r := shr(f, r)
        }
        assembly {
            let f := shl(3, gt(r, 0xFF))
            msb := or(msb, f)
            r := shr(f, r)
        }
        assembly {
            let f := shl(2, gt(r, 0xF))
            msb := or(msb, f)
            r := shr(f, r)
        }
        assembly {
            let f := shl(1, gt(r, 0x3))
            msb := or(msb, f)
            r := shr(f, r)
        }
        assembly {
            let f := gt(r, 0x1)
            msb := or(msb, f)
        }

        if (msb >= 128) r = ratio >> (msb - 127);
        else r = ratio << (127 - msb);

        int256 log_2 = (int256(msb) - 128) << 64;

        assembly {
            r := shr(127, mul(r, r))
            let f := shr(128, r)
            log_2 := or(log_2, shl(63, f))
            r := shr(f, r)
        }
        assembly {
            r := shr(127, mul(r, r))
            let f := shr(128, r)
            log_2 := or(log_2, shl(62, f))
            r := shr(f, r)
        }
        assembly {
            r := shr(127, mul(r, r))
            let f := shr(128, r)
            log_2 := or(log_2, shl(61, f))
            r := shr(f, r)
        }
        assembly {
            r := shr(127, mul(r, r))
            let f := shr(128, r)
            log_2 := or(log_2, shl(60, f))
            r := shr(f, r)
        }
        assembly {
            r := shr(127, mul(r, r))
            let f := shr(128, r)
            log_2 := or(log_2, shl(59, f))
            r := shr(f, r)
        }
        assembly {
            r := shr(127, mul(r, r))
            let f := shr(128, r)
            log_2 := or(log_2, shl(58, f))
            r := shr(f, r)
        }
        assembly {
            r := shr(127, mul(r, r))
            let f := shr(128, r)
            log_2 := or(log_2, shl(57, f))
            r := shr(f, r)
        }
        assembly {
            r := shr(127, mul(r, r))
            let f := shr(128, r)
            log_2 := or(log_2, shl(56, f))
            r := shr(f, r)
        }
        assembly {
            r := shr(127, mul(r, r))
            let f := shr(128, r)
            log_2 := or(log_2, shl(55, f))
            r := shr(f, r)
        }
        assembly {
            r := shr(127, mul(r, r))
            let f := shr(128, r)
            log_2 := or(log_2, shl(54, f))
            r := shr(f, r)
        }
        assembly {
            r := shr(127, mul(r, r))
            let f := shr(128, r)
            log_2 := or(log_2, shl(53, f))
            r := shr(f, r)
        }
        assembly {
            r := shr(127, mul(r, r))
            let f := shr(128, r)
            log_2 := or(log_2, shl(52, f))
            r := shr(f, r)
        }
        assembly {
            r := shr(127, mul(r, r))
            let f := shr(128, r)
            log_2 := or(log_2, shl(51, f))
            r := shr(f, r)
        }
        assembly {
            r := shr(127, mul(r, r))
            let f := shr(128, r)
            log_2 := or(log_2, shl(50, f))
        }

        int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number

        int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);
        int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);

        tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;
    }
}

File 12 of 12 : TransferHelper.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity >=0.6.0;

// helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false
library TransferHelper {
    function safeApprove(
        address token,
        address to,
        uint256 value
    ) internal {
        // bytes4(keccak256(bytes('approve(address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));
        require(
            success && (data.length == 0 || abi.decode(data, (bool))),
            'TransferHelper::safeApprove: approve failed'
        );
    }

    function safeTransfer(
        address token,
        address to,
        uint256 value
    ) internal {
        // bytes4(keccak256(bytes('transfer(address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
        require(
            success && (data.length == 0 || abi.decode(data, (bool))),
            'TransferHelper::safeTransfer: transfer failed'
        );
    }

    function safeTransferFrom(
        address token,
        address from,
        address to,
        uint256 value
    ) internal {
        // bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
        require(
            success && (data.length == 0 || abi.decode(data, (bool))),
            'TransferHelper::transferFrom: transferFrom failed'
        );
    }

    function safeTransferETH(address to, uint256 value) internal {
        (bool success, ) = to.call{value: value}(new bytes(0));
        require(success, 'TransferHelper::safeTransferETH: ETH transfer failed');
    }
}

Settings
{
  "viaIR": true,
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {
    "contracts/libs/Logarithm.sol": {
      "Logarithm": "0x16882fd345b2ed4e6578f538d7141af5702e6d4a"
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_inscriptionFactory","type":"address"},{"internalType":"address","name":"_weth","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint128","name":"ethAmount","type":"uint128"},{"indexed":false,"internalType":"uint128","name":"tokenAmount","type":"uint128"},{"indexed":false,"internalType":"uint128","name":"tokenLiquidity","type":"uint128"}],"name":"MintDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint128","name":"etherAmount","type":"uint128"},{"indexed":false,"internalType":"uint128","name":"senderToken","type":"uint128"},{"indexed":false,"internalType":"uint128","name":"liquidityToken","type":"uint128"},{"indexed":false,"internalType":"uint16","name":"refundFee","type":"uint16"}],"name":"Refund","type":"event"},{"inputs":[],"name":"TICK_SPACING","outputs":[{"internalType":"int24","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNISWAP_FEE","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"slippage","type":"uint16"}],"name":"addLiquidity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"collectFee","outputs":[{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"deposits","outputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint128","name":"liquidity","type":"uint128"},{"internalType":"address","name":"token0","type":"address"},{"internalType":"address","name":"token1","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint128","name":"cap","type":"uint128"},{"internalType":"uint128","name":"limitPerMint","type":"uint128"},{"internalType":"address","name":"onlyContractAddress","type":"address"},{"internalType":"uint32","name":"maxMintSize","type":"uint32"},{"internalType":"uint64","name":"inscriptionId","type":"uint64"},{"internalType":"uint128","name":"onlyMinQuantity","type":"uint128"},{"internalType":"uint128","name":"crowdFundingRate","type":"uint128"},{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint40","name":"freezeTime","type":"uint40"},{"internalType":"uint40","name":"timestamp","type":"uint40"},{"internalType":"uint16","name":"liquidityTokenPercent","type":"uint16"},{"internalType":"address","name":"ifoContractAddress","type":"address"},{"internalType":"uint16","name":"refundFee","type":"uint16"},{"internalType":"uint40","name":"startTime","type":"uint40"},{"internalType":"uint40","name":"duration","type":"uint40"},{"internalType":"address","name":"customizedConditionContractAddress","type":"address"},{"internalType":"uint96","name":"maxRollups","type":"uint96"},{"internalType":"address","name":"deployer","type":"address"},{"internalType":"string","name":"tick","type":"string"},{"internalType":"uint16","name":"liquidityEtherPercent","type":"uint16"},{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"customizedVestingContractAddress","type":"address"},{"internalType":"bool","name":"isIFOMode","type":"bool"},{"internalType":"bool","name":"isWhitelist","type":"bool"},{"internalType":"bool","name":"isVesting","type":"bool"},{"internalType":"bool","name":"isVoted","type":"bool"},{"internalType":"string","name":"logoUrl","type":"string"}],"internalType":"struct IInscriptionFactory.Token","name":"_token","type":"tuple"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"inscriptionFactory","outputs":[{"internalType":"contract IInscriptionFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liquidityAdded","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"mintData","outputs":[{"internalType":"uint128","name":"ethAmount","type":"uint128"},{"internalType":"uint128","name":"tokenAmount","type":"uint128"},{"internalType":"uint128","name":"tokenLiquidity","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nonfungiblePositionManager","outputs":[{"internalType":"contract INonfungiblePositionManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolData","outputs":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"address","name":"token0","type":"address"},{"internalType":"address","name":"token1","type":"address"},{"internalType":"uint256","name":"uintRate","type":"uint256"},{"internalType":"uint160","name":"sqrtPriceX96","type":"uint160"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint128","name":"pageNo","type":"uint128"},{"internalType":"uint128","name":"pageSize","type":"uint128"}],"name":"positions","outputs":[{"components":[{"internalType":"uint96","name":"nonce","type":"uint96"},{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"token0","type":"address"},{"internalType":"address","name":"token1","type":"address"},{"internalType":"uint24","name":"fee","type":"uint24"},{"internalType":"int24","name":"tickLower","type":"int24"},{"internalType":"int24","name":"tickUpper","type":"int24"},{"internalType":"uint128","name":"liquidity","type":"uint128"},{"internalType":"uint256","name":"feeGrowthInside0LastX128","type":"uint256"},{"internalType":"uint256","name":"feeGrowthInside1LastX128","type":"uint256"},{"internalType":"uint128","name":"tokensOwed0","type":"uint128"},{"internalType":"uint128","name":"tokensOwed1","type":"uint128"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"internalType":"struct InitialFairOffering.Position[]","name":"_positions","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"refund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"},{"internalType":"uint128","name":"_ethAmount","type":"uint128"},{"internalType":"uint128","name":"_tokenAmount","type":"uint128"},{"internalType":"uint128","name":"_tokenLiquidity","type":"uint128"}],"name":"setMintData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"uint128","name":"cap","type":"uint128"},{"internalType":"uint128","name":"limitPerMint","type":"uint128"},{"internalType":"address","name":"onlyContractAddress","type":"address"},{"internalType":"uint32","name":"maxMintSize","type":"uint32"},{"internalType":"uint64","name":"inscriptionId","type":"uint64"},{"internalType":"uint128","name":"onlyMinQuantity","type":"uint128"},{"internalType":"uint128","name":"crowdFundingRate","type":"uint128"},{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint40","name":"freezeTime","type":"uint40"},{"internalType":"uint40","name":"timestamp","type":"uint40"},{"internalType":"uint16","name":"liquidityTokenPercent","type":"uint16"},{"internalType":"address","name":"ifoContractAddress","type":"address"},{"internalType":"uint16","name":"refundFee","type":"uint16"},{"internalType":"uint40","name":"startTime","type":"uint40"},{"internalType":"uint40","name":"duration","type":"uint40"},{"internalType":"address","name":"customizedConditionContractAddress","type":"address"},{"internalType":"uint96","name":"maxRollups","type":"uint96"},{"internalType":"address","name":"deployer","type":"address"},{"internalType":"string","name":"tick","type":"string"},{"internalType":"uint16","name":"liquidityEtherPercent","type":"uint16"},{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"customizedVestingContractAddress","type":"address"},{"internalType":"bool","name":"isIFOMode","type":"bool"},{"internalType":"bool","name":"isWhitelist","type":"bool"},{"internalType":"bool","name":"isVesting","type":"bool"},{"internalType":"bool","name":"isVoted","type":"bool"},{"internalType":"string","name":"logoUrl","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenIdCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalBackToDeployAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalRefundedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uniswapV3Factory","outputs":[{"internalType":"contract IUniswapV3Factory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"weth","outputs":[{"internalType":"contract IWETH","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

Deployed Bytecode

0x60c080604052600436101561003e575b50361561001b57600080fd5b6001546001600160a01b03163381900361003157005b61003c903490613b4c565b005b600090813560e01c9081633fc8cef3146130935750806346ca626b146130775780634e69dfff14611a59578063590e1ae3146114a25780635b5491821461147b578063768d2ab61461145d5780638bca8e5914610af25780639a47083114610a955780639fc6a1dc14610a6c578063a167722814610a4f578063a969ff0a14610951578063b02c43d0146108ef578063b44a2722146108c0578063ba79f088146106d0578063c981523e146105a7578063cd1e035514610589578063d58778d61461055f578063d944392314610539578063f127394c1461051b578063fc0c546a1461017f5763fee151ae0361000f573461017c578060031936011261017c5760a0600180821b0380600954169080600a54169080600b5416600c5491600d5416926040519485526020850152604084015260608301526080820152f35b80fd5b503461017c578060031936011261017c57600e54600f5460105490601154926012549060135460018060a01b0360145416604051600081601554916101c383613222565b80835292600181169081156104fc57506001146104ad575b6101e79250038261311d565b61ffff6016541690604051926000846017549161020383613222565b808352926001811690811561048e575060011461043f575b6102279250038561311d565b601854946040519760009b60195461023e81613222565b808c52906001811690811561041d57506001146103d6575b508988999a9b9c9d03610269908c61311d565b6040519c8d809d6001600160801b039c8d8116835260801c6020830152600160a01b600190038116604083015260a09c818e92831c63ffffffff16606085015260c01c6080840152831691015260801c60c08d0152600160a01b60019003811660e08d015264ffffffffff908c82828d1c169061010001528c828260c81c1690610120015260f01c6101408d0152600160a01b6001900382166101608d0152818a1c61ffff166101808d01528160b01c166101a08c015260d81c6101c08b0152600160a01b6001900381166101e08b0152871c6102008a0152610220890152610360806102408a0152880161035d9161325c565b906102608801528681036102808801526103769161325c565b92600160a01b6001900382166102a08701521c60ff1615156102c08501528060a81c60ff1615156102e08501528060b01c60ff16151561030085015260b81c60ff1615156103208401528281036103408401526103d29161325c565b0390f35b9c5060196000528c600080516020613c168339815191526000915b821061040557508a016020019c5089610256565b6001818d60208581955492010152019101908e6103f1565b60ff19166020808e019190915291151560051b8c019091019d508a9050610256565b50906017600052600080516020613bf6833981519152906000915b8183106104725750509060206102279282010161021b565b6020919350806001915483858b0101520191019091869261045a565b6020925061022794915060ff191682840152151560051b82010161021b565b50906015600052600080516020613bd6833981519152906000915b8183106104e05750509060206101e7928201016101db565b60209193508060019154838588010152019101909183926104c8565b602092506101e794915060ff191682840152151560051b8201016101db565b503461017c578060031936011261017c576020600654604051908152f35b503461017c578060031936011261017c57602060ff60025460a01c166040519015158152f35b503461017c57602036600319011261017c5760406020916004358152600583522054604051908152f35b503461017c578060031936011261017c576020600854604051908152f35b503461017c57604036600319011261017c576001600160801b039060043582811681036106cb576105e0906105da61313e565b9061355e565b60405191602080840190808552835180925280604086019401925b8281106106085785850386f35b835180516001600160601b03168652808301516001600160a01b03908116878501526040808301518216908801526060808301519091169087015260808082015162ffffff169087015260a080820151600290810b9188019190915260c08083015190910b9087015260e08082015189169087015261010080820151908701526101208082015190870152610140808201518916908701526101608082015189169087015261018090810151908601526101a090940193928101926001016105fb565b600080fd5b503461017c57608036600319011261017c576106ea613168565b6106f261313e565b906001600160801b03906044358281168082036106cb5760643594848616928387036106cb576011546001600160a01b03969087163303610870578083169586151580610867575b8061085e575b80610853575b1561080e577fa84e391e1ad730c18ded298ed9d480547628502da6d661accadeafe88e6cf768988260018c60406107bc61079560809e6107dc98169a8b85526003602052868486205416613543565b988a84526003602052828420866001600160801b03199b168b825416178091558f1c613543565b918981526003602052209083888354928f1b169116178155015416613543565b9289526003602052600160408a200192169082541617905560405192338452602084015260408301526060820152a180f35b60405162461bcd60e51b815260206004820152601e60248201527f73657445746865724c69717569646974792077726f6e6720706172616d7300006044820152606490fd5b508781161515610746565b50851515610740565b5084151561073a565b60405162461bcd60e51b815260206004820152602260248201527f4f6e6c792063616c6c2066726f6d20696e736372697074696f6e20616c6c6f77604482015261195960f21b6064820152608490fd5b503461017c578060031936011261017c57602060405173c36442b4a4522e871399cd717abdd847ab11fe888152f35b503461017c57602036600319011261017c576040608091600435815260046020522060018060a01b0380825416916001600160801b03600182015416916003816002840154169201541691604051938452602084015260408301526060820152f35b503461017c57602036600319011261017c5760405161096f816130cb565b60043581526020810130815260408201906001600160801b03828180945260608501928284526040519563fc6f786560e01b875251600487015260018060a01b03905116602486015251166044840152511660648201526040816084818573c36442b4a4522e871399cd717abdd847ab11fe885af18015610a445782918391610a03575b6040838382519182526020820152f35b9150506040813d604011610a3c575b81610a1f6040938361311d565b81010312610a38576040915060208151910151386109f3565b5080fd5b3d9150610a12565b6040513d84823e3d90fd5b503461017c578060031936011261017c576020604051610bb88152f35b503461017c578060031936011261017c576002546040516001600160a01b039091168152602090f35b503461017c57602036600319011261017c576060906001906040906001600160a01b03610ac0613168565b1681526003602052208054906001600160801b0392839101541690604051928116835260801c60208301526040820152f35b503461017c57602036600319011261017c5761ffff6004351680600435036106cb576127101061142757601154604051634c3d323d60e01b81526001600160a01b0390911690602081600481855afa90811561141c5783916113ea575b5060135460a01c8091106113b1578254600154604051630b4c774160e11b81526001600160a01b039182166004820181905260248201869052610bb860448301529392909160209183916064918391165afa9081156112d1578591611373575b506001600160a01b0316156113145761ffff601654169182156112dc576020602494604051958680926370a0823160e01b82523060048301525afa9384156112d157859461129d575b508315611258576040516370a0823160e01b815230600482015292602084602481855afa93841561124d578694611219575b5083156111db57612710610c4a61ffff610c43846132b0565b16866132da565b04926004602060018060a01b03600254166040519283809263cb06bfdb60e01b82525afa9081156111d057889161118d575b50610c8961ffff916132b0565b1602806001600160601b03811603611179576305f5e1006001600160801b03610cdb89959461ffff610cd4610cce85976001600160601b0360105460801c91166132ed565b926132b0565b16906132ed565b160416610cea84600754613339565b1161116c57803b15610a3857818091602460405180948193632e1a7d4d60e01b83528860048401525af18015610a4457611154575b5050601454610d659290610d3d9083906001600160a01b0316613b4c565b610d4982600754613339565b6007555b6002805460ff60a01b1916600160a01b179055613346565b6001546011546001600160a01b039182169291168083111561114d57919290915b610d9082826139fa565b610d9a83856139fa565b612710610db561ffff610dae6004356132b0565b16846132da565b0491612710610dcb61ffff610c436004356132b0565b0460405193846101608101106001600160401b036101608701111761113757610160850160405260018060a01b038416855260018060a01b0387166020860152610bb86040860152620d89b3196060860152620d89b460808601528260a08601528560c086015260e0850152610100840152306101208401524261014084015261014060405193634418b22b60e11b855260018060a01b03815116600486015260018060a01b03602082015116602486015262ffffff6040820151166044860152606081015160020b6064860152608081015160020b608486015260a081015160a486015260c081015160c486015260e081015160e486015261010081015161010486015260018060a01b0361012082015116610124860152015161014484015273c36442b4a4522e871399cd717abdd847ab11fe8892608081610164818a885af193841561112c578790889289966110d6575b5060405191829163133f757160e31b83528160048401528260246101809586935afa9182156110cb578a908b948c9461108a575b5050818b52600460205260408b20546001600160a01b03161561104f575b9060039160405191610f82836130cb565b3383526001600160801b036020840195168552604083019160018060a01b03168252606083019560018060a01b031686528c52600460205260408c209160018060a01b03905116936001600160601b0360a01b94858454161783556001600160801b03600184019151166001600160801b0319825416179055600282019060018060a01b0390511684825416179055019160018060a01b039051169082541617905510611040575b5010611034575080f35b61103d90613af8565b80f35b61104990613af8565b3861102a565b6006548b5260056020528160408c2055600654600019811461107657600101600655610f71565b634e487b7160e01b8c52601160045260248cfd5b91509193506110ae9250803d106110c4575b6110a6818361311d565b81019061346e565b5050505097955050505092509192913880610f53565b503d61109c565b6040513d8c823e3d90fd5b92509450506080813d608011611124575b816110f46080938361311d565b810103126111205780519061110b6020820161345a565b50606060408201519101519190919438610f1f565b8680fd5b3d91506110e7565b6040513d89823e3d90fd5b634e487b7160e01b600052604160045260246000fd5b9291610d86565b61115d906130b8565b611168578338610d1f565b8380fd5b50610d6592915090610d4d565b634e487b7160e01b87526011600452602487fd5b90506020813d6020116111c8575b816111a86020938361311d565b810103126111c4575161ffff811681036111c457610c89610c7c565b8780fd5b3d915061119b565b6040513d8a823e3d90fd5b60405162461bcd60e51b81526020600482015260166024820152751b9bc8195d1a081a5b88199d1bc818dbdb9d1c9858dd60521b6044820152606490fd5b9093506020813d602011611245575b816112356020938361311d565b810103126106cb57519238610c2a565b3d9150611228565b6040513d88823e3d90fd5b60405162461bcd60e51b815260206004820152601860248201527f6e6f20746f6b656e20696e2066746f20636f6e747261637400000000000000006044820152606490fd5b9093506020813d6020116112c9575b816112b96020938361311d565b810103126106cb57519238610bf8565b3d91506112ac565b6040513d87823e3d90fd5b60405162461bcd60e51b815260206004820152601060248201526f1b9bc81b1a5c5d5a591a5d1e4818591960821b6044820152606490fd5b60405162461bcd60e51b815260206004820152603160248201527f506f6f6c206e6f742065786973742c2063726561746520706f6f6c20696e20756044820152706e69737761705633206d616e75616c6c7960781b6064820152608490fd5b90506020813d6020116113a9575b8161138e6020938361311d565b810103126113a55761139f9061329c565b38610baf565b8480fd5b3d9150611381565b60405162461bcd60e51b81526020600482015260116024820152701b5a5b9d081b9bdd08199a5b9a5cda1959607a1b6044820152606490fd5b90506020813d602011611414575b816114056020938361311d565b810103126106cb575138610b4f565b3d91506113f8565b6040513d85823e3d90fd5b60405162461bcd60e51b815260206004820152600e60248201526d39b634b83830b3b29032b93937b960911b6044820152606490fd5b503461017c578060031936011261017c576020600754604051908152f35b503461017c578060031936011261017c57546040516001600160a01b039091168152602090f35b503461017c578060031936011261017c57338152600360208181526001600160801b03918260408520541615611a2057601154604051634c3d323d60e01b81526001600160a01b0393918416908281600481855afa90811561112c5787916119f3575b5060135460a01c11156119ba576018548460ff8260b01c1691826119ae575b5050156117de5750848360185416338252838352604082205460801c90803b156117b257604051633aa8f69760e01b81523360048201526001600160801b0392909216602483015282908290604490829084905af18015610a44576117ca575b50505b33855281815260019284846040882001541690612710908782886115b661ffff968760125460a01c16906132ed565b16049282601154163383528787526115d6858b8b60408720015416613353565b90803b1561116857604051632770a7eb60e21b81523060048201526001600160801b0392909216602483015283908290604490829084905af190811561141c5783916117b6575b50503382528686528861163e816040852054168760125460a01c16906132ed565b16049187541633825286865261165a838a604085205416613353565b813b156117b2578960248492836040519586948593632e1a7d4d60e01b85521660048401525af18015610a4457611797575b50918761172c7f112f3d444d9b69149acde2cbc8c346d070fcc2e8a4efd59048297f3dae14a36f959361171761170e8960009d8d604060a09b8f3382528086526116e6856116df8b828787205416613353565b1633613b4c565b6116ff6008543384528288528484205460801c90613339565b95338352522001541690613339565b84861690613346565b600855338c528888528260408d205416613353565b92338b5287875261174b60408c2093838b865460801c96015416613353565b90601254861c16928260405195338752168886015260408501521660608301526080820152a1338552526040832090810180546fffffffffffffffffffffffffffffffff191690555580f35b906117a581959394926130b8565b611168579190923861168c565b8280fd5b6117bf906130b8565b610a3857813861161d565b6117d3906130b8565b6113a5578438611584565b6040516370a0823160e01b81523360048201528281602481855afa90811561112c578791611981575b50338752838352604087205460801c1161193c57604051636eb1769f60e11b81523360048201523060248201528281604481855afa90811561112c57879161190f575b50338752838352604087205460801c116118ca578590338252838352604082205460801c813b156117b25760405163079cc67960e41b81523360048201526001600160801b0391909116602482015291908290604490829084905af1801561124d576118b7575b50611587565b6118c3909591956130b8565b93386118b1565b60405162461bcd60e51b815260048101839052601960248201527f596f757220616c6c6f77616e6365206e6f7420656e6f756768000000000000006044820152606490fd5b90508281813d8311611935575b611926818361311d565b8101031261112057513861184a565b503d61191c565b60405162461bcd60e51b815260048101839052601d60248201527f596f75722062616c616e636520746f6b656e206e6f7420656e6f7567680000006044820152606490fd5b90508281813d83116119a7575b611998818361311d565b81010312611120575138611807565b503d61198e565b16151590508438611524565b60405162461bcd60e51b81526004810183905260116024820152701b5a5b9d081a185cc8199a5b9a5cda1959607a1b6044820152606490fd5b90508281813d8311611a19575b611a0a818361311d565b81010312611120575138611505565b503d611a00565b60405162461bcd60e51b81526004810183905260116024820152701e5bdd481a185d99481b9bdd081b5a5b9d607a1b6044820152606490fd5b503461017c576003199060203683011261017c576001600160401b036004351161017c5761036080926004353603011261017c576040519182018281106001600160401b03821117612f0357604052611ab6600435600401613154565b8252611ac6602460043501613154565b6020830152611ad960446004350161317e565b60408301526064600435013563ffffffff81168103610a38576060830152608460043501356001600160401b0381168103610a38576080830152611b2160a460043501613154565b60a0830152611b3460c460043501613154565b60c0830152611b4760e46004350161317e565b60e0830152611b5b61010460043501613192565b610100830152611b7061012460043501613192565b610120830152611b85610144600435016131a4565b610140830152611b9a6101646004350161317e565b610160830152611baf610184600435016131a4565b610180830152611bc46101a460043501613192565b6101a0830152611bd96101c460043501613192565b6101c0830152611bee6101e46004350161317e565b6101e083015260043561020401356001600160601b038116900361017c576102046004350135610200830152611c296102246004350161317e565b61022083015261024460043501356001600160401b038111610a3857611c569060043691813501016131ce565b610240830152611c6b610264600435016131a4565b61026083015261028460043501356001600160401b038111610a3857611c989060043691813501016131ce565b610280830152611cad6102a46004350161317e565b6102a0830152611cc26102c460043501613215565b6102c0830152611cd76102e460043501613215565b6102e0830152611cec61030460043501613215565b610300830152611d0161032460043501613215565b61032083015261034460043501356001600160401b038111610a3857611d2e9060043691813501016131ce565b6103408301526002546001600160a01b03163303613033576001600160401b0360808301511615612ffb576001600160801b038251166001600160801b0319602084015160801b1617600e5560018060a01b0360408301511663ffffffff60a01b606084015160a01b166001600160401b0360c01b608085015160c01b16911717600f556001600160801b0360a0830151166001600160801b031960c084015160801b161760105560018060a01b0360e08301511664ffffffffff60a01b61010084015160a01b1664ffffffffff60c81b61012085015160c81b169061014085015161ffff60f01b9060f01b169217171760115560018060a01b036101608301511661ffff60a01b61018084015160a01b166101a08401519064ffffffffff60d81b6101c086015160d81b1692179064ffffffffff60b01b9060b01b16171760125560018060a01b036101e0830151166001600160601b0360a01b61020084015160a01b161760135560018060a01b03610220830151166001600160601b0360a01b60145416176014556102408201519182516001600160401b038111612e0b57611eda601554613222565b601f8111612f94575b506020601f8211600114612f2257839482939492612f17575b50508160011b916000199060031b1c1916176015555b61ffff6102608201511661ffff1960165416176016556102808101519182516001600160401b038111612f0357611f4a601754613222565b601f8111612e9c575b506020601f8211600114612e2a57829394829392612e1f575b50508160011b916000199060031b1c1916176017555b60018060a01b036102a0830151166018549060ff60a01b6102c0850151151560a01b1660ff60a81b6102e0860151151560a81b169060ff60b01b610300870151151560b01b169260ff60b81b610320880151151560b81b16946001600160401b0360c01b1617171717176018556103408201519182516001600160401b038111612e0b57612011601954613222565b601f8111612da4575b506020601f8211600114612d3257839482939492612d27575b50508160011b916000199060031b1c1916176019555b60018060a01b03600154169060e060018060a01b03910151169081819060105460801c61ffff601654169060115460f01c655af3107a40006001600160801b036120b06120a4600e5460801c9664e8d4a510008097046132ed565b61ffff610cd4866132b0565b16026001600160801b038116908103612d1357916120da6001600160801b0394926120e29461330b565b91049061330b565b16928315612cdd57808210156127a55750506120fd826138b1565b60020b8481121561279f57600160ff1b811461278b57808503905b620d89e882136127625785906001831615612750576001600160881b036ffffcb933bd6fad37aa2d162d1a5940015b16926002811661271e575b600481166126ec575b600881166126ba575b60108116612688575b60208116612656575b60408116612624575b608081166125f2575b61010081166125c0575b610200811661258e575b610400811661255c575b610800811661252a575b61100081166124f8575b61200081166124c6575b6140008116612494575b6180008116612462575b620100008116612430575b6202000081166123ff575b6204000081166123bb575b620800001661238f575b1361236c575b63ffffffff81166123615761222f85915b6001600160a01b039260ff169060201c613339565b16905b6040516309f56ab160e11b81526001600160a01b039485166004820181905291851660248201819052610bb860448301529290941660648501819052936020816084818973c36442b4a4522e871399cd717abdd847ab11fe885af190811561124d578691612323575b506040516001600160401b0360a0820191821091111761230f5760018060a01b03166001600160601b0360a01b60095416176009556001600160601b0360a01b600a541617600a556001600160601b0360a01b600b541617600b55600c556001600160601b0360a01b600d541617600d5580f35b634e487b7160e01b86526041600452602486fd5b90506020813d602011612359575b8161233e6020938361311d565b810103126123555761234f9061329c565b3861229b565b8580fd5b3d9150612331565b61222f60019161221a565b801561237b5760001904612209565b634e487b7160e01b85526012600452602485fd5b9190506b048a170391f7dc42444e8fa2908082810204821481151715611179570260801c908590612203565b929091506d2216e584f5fa1ea926041bedfe989080828102048214811517156123eb570260801c918691906121f9565b634e487b7160e01b88526011600452602488fd5b929091506e5d6af8dedb81196699c329225ee6049080828102048214811517156123eb570260801c918691906121ee565b929091506f09aa508b5b7a84e1c677de54f3e99bc99080828102048214811517156123eb570260801c918691906121e3565b929091506f31be135f97d08fd981231505542fcfa69080828102048214811517156123eb570260801c918691906121d8565b929091506f70d869a156d2a1b890bb3df62baf32f79080828102048214811517156123eb570260801c918691906121ce565b929091506fa9f746462d870fdf8a65dc1f90e061e59080828102048214811517156123eb570260801c918691906121c4565b929091506fd097f3bdfd2022b8845ad8f792aa58259080828102048214811517156123eb570260801c918691906121ba565b929091506fe7159475a2c29b7443b29c7fa6e889d99080828102048214811517156123eb570260801c918691906121b0565b929091506ff3392b0822b70005940c7a398e4b70f39080828102048214811517156123eb570260801c918691906121a6565b929091506ff987a7253ac413176f2b074cf7815e549080828102048214811517156123eb570260801c9186919061219c565b929091506ffcbe86c7900a88aedcffc83b479aa3a49080828102048214811517156123eb570260801c91869190612192565b929091506ffe5dee046a99a2a811c461f1969c30539080828102048214811517156123eb570260801c91869190612188565b929091506fff2ea16466c96a3843ec78b326b528619080828102048214811517156123eb570260801c9186919061217f565b929091506fff973b41fa98c081472e6896dfb254c09080828102048214811517156123eb570260801c91869190612176565b929091506fffcb9843d60f6159c9db58835c9266449080828102048214811517156123eb570260801c9186919061216d565b929091506fffe5caca7e10e4e61c3624eaa0941cd09080828102048214811517156123eb570260801c91869190612164565b929091506ffff2e50f5f656932ef12357cf3c7fdcc9080828102048214811517156123eb570260801c9186919061215b565b929091506ffff97272373d413259a46990580e213a9080828102048214811517156123eb570260801c91869190612152565b6001600160881b03600160801b612147565b60405162461bcd60e51b81526020600482015260016024820152601560fa1b6044820152606490fd5b634e487b7160e01b85526011600452602485fd5b80612118565b9150925091906ec097ce7bc90715b34b9f100000000004906127c6826138b1565b60020b84811215612cd757600160ff1b811461278b57808503905b620d89e882136127625785906001831615612cc5576001600160881b036ffffcb933bd6fad37aa2d162d1a5940015b169260028116612c93575b60048116612c61575b60088116612c2f575b60108116612bfd575b60208116612bcb575b60408116612b99575b60808116612b67575b6101008116612b35575b6102008116612b03575b6104008116612ad1575b6108008116612a9f575b6110008116612a6d575b6120008116612a3b575b6140008116612a09575b61800081166129d7575b6201000081166129a5575b620200008116612974575b620400008116612944575b6208000016612918575b13612909575b63ffffffff81166128fe576128f785916001600160a01b039260ff169060201c613339565b1690612232565b6128f760019161221a565b801561237b57600019046128d2565b9190506b048a170391f7dc42444e8fa2908082810204821481151715611179570260801c9085906128cc565b929091506d2216e584f5fa1ea926041bedfe989080828102048214811517156123eb570260801c918691906128c2565b929091506e5d6af8dedb81196699c329225ee6049080828102048214811517156123eb570260801c918691906128b7565b929091506f09aa508b5b7a84e1c677de54f3e99bc99080828102048214811517156123eb570260801c918691906128ac565b929091506f31be135f97d08fd981231505542fcfa69080828102048214811517156123eb570260801c918691906128a1565b929091506f70d869a156d2a1b890bb3df62baf32f79080828102048214811517156123eb570260801c91869190612897565b929091506fa9f746462d870fdf8a65dc1f90e061e59080828102048214811517156123eb570260801c9186919061288d565b929091506fd097f3bdfd2022b8845ad8f792aa58259080828102048214811517156123eb570260801c91869190612883565b929091506fe7159475a2c29b7443b29c7fa6e889d99080828102048214811517156123eb570260801c91869190612879565b929091506ff3392b0822b70005940c7a398e4b70f39080828102048214811517156123eb570260801c9186919061286f565b929091506ff987a7253ac413176f2b074cf7815e549080828102048214811517156123eb570260801c91869190612865565b929091506ffcbe86c7900a88aedcffc83b479aa3a49080828102048214811517156123eb570260801c9186919061285b565b929091506ffe5dee046a99a2a811c461f1969c30539080828102048214811517156123eb570260801c91869190612851565b929091506fff2ea16466c96a3843ec78b326b528619080828102048214811517156123eb570260801c91869190612848565b929091506fff973b41fa98c081472e6896dfb254c09080828102048214811517156123eb570260801c9186919061283f565b929091506fffcb9843d60f6159c9db58835c9266449080828102048214811517156123eb570260801c91869190612836565b929091506fffe5caca7e10e4e61c3624eaa0941cd09080828102048214811517156123eb570260801c9186919061282d565b929091506ffff2e50f5f656932ef12357cf3c7fdcc9080828102048214811517156123eb570260801c91869190612824565b929091506ffff97272373d413259a46990580e213a9080828102048214811517156123eb570260801c9186919061281b565b6001600160881b03600160801b612810565b806127e1565b60405162461bcd60e51b815260206004820152600e60248201526d75696e742072617465207a65726f60901b6044820152606490fd5b634e487b7160e01b89526011600452602489fd5b015190503880612033565b60198452600080516020613c1683398151915290845b601f1984168110612d8c5750600193949583601f19811610612d73575b505050811b01601955612049565b015160001960f88460031b161c19169055388080612d65565b9091602060018192858a015181550193019101612d48565b60198452601f820160051c600080516020613c168339815191520160208310612df6575b601f820160051c600080516020613c16833981519152018110612deb575061201a565b848155600101612dc8565b50600080516020613c16833981519152612dc8565b634e487b7160e01b83526041600452602483fd5b015190503880611f6c565b60178352600080516020613bf683398151915290835b601f1984168110612e845750600193949583601f19811610612e6b575b505050811b01601755611f82565b015160001960f88460031b161c19169055388080612e5d565b9091602060018192858a015181550193019101612e40565b60178352601f820160051c600080516020613bf68339815191520160208310612eee575b601f820160051c600080516020613bf6833981519152018110612ee35750611f53565b838155600101612ec0565b50600080516020613bf6833981519152612ec0565b634e487b7160e01b82526041600452602482fd5b015190503880611efc565b60158452600080516020613bd683398151915290845b601f1984168110612f7c5750600193949583601f19811610612f63575b505050811b01601555611f12565b015160001960f88460031b161c19169055388080612f55565b9091602060018192858a015181550193019101612f38565b60158452601f820160051c600080516020613bd68339815191520160208310612fe6575b601f820160051c600080516020613bd6833981519152018110612fdb5750611ee3565b848155600101612fb8565b50600080516020613bd6833981519152612fb8565b60405162461bcd60e51b815260206004820152601060248201526f746f6b656e20646174612077726f6e6760801b6044820152606490fd5b606460405162461bcd60e51b815260206004820152602060248201527f4f6e6c7920696e736372697074696f6e20666163746f727920616c6c6f7765646044820152fd5b503461017c578060031936011261017c576020604051603c8152f35b905034610a385781600319360112610a38576001546001600160a01b03168152602090f35b6001600160401b03811161113757604052565b608081019081106001600160401b0382111761113757604052565b6101a081019081106001600160401b0382111761113757604052565b602081019081106001600160401b0382111761113757604052565b90601f801991011681019081106001600160401b0382111761113757604052565b602435906001600160801b03821682036106cb57565b35906001600160801b03821682036106cb57565b600435906001600160a01b03821682036106cb57565b35906001600160a01b03821682036106cb57565b359064ffffffffff821682036106cb57565b359061ffff821682036106cb57565b6001600160401b03811161113757601f01601f191660200190565b81601f820112156106cb578035906131e5826131b3565b926131f3604051948561311d565b828452602083830101116106cb57816000926020809301838601378301015290565b359081151582036106cb57565b90600182811c92168015613252575b602083101461323c57565b634e487b7160e01b600052602260045260246000fd5b91607f1691613231565b919082519283825260005b848110613288575050826000602080949584010152601f8019910116010190565b602081830181015184830182015201613267565b51906001600160a01b03821682036106cb57565b9061ffff809216612710039182116132c457565b634e487b7160e01b600052601160045260246000fd5b818102929181159184041417156132c457565b9190916001600160801b03808094169116029182169182036132c457565b906001600160801b0380911691821561332357160490565b634e487b7160e01b600052601260045260246000fd5b919082018092116132c457565b919082039182116132c457565b6001600160801b0391821690821603919082116132c457565b6001600160401b0381116111375760051b60200190565b9061338d8261336c565b60409061339c8251918261311d565b83815280936133ad601f199161336c565b019160005b8381106133bf5750505050565b60209082516133cd816130e6565b60008152826000818301526000858301526000606083015260006080830152600060a0830152600060c0830152600060e0830152600061010083015260006101208301526000610140830152600061016083015260006101808301528286010152016133b2565b6001600160801b038091169081146132c45760010190565b51908160020b82036106cb57565b51906001600160801b03821682036106cb57565b9190826101809103126106cb5781516001600160601b03811681036106cb579161349a6020820161329c565b916134a76040830161329c565b916134b46060820161329c565b91608082015162ffffff811681036106cb57916134d360a0820161344c565b916134e060c0830161344c565b916134ed60e0820161345a565b91610100820151916101208101519161351661016061350f610140850161345a565b930161345a565b90565b805182101561352d5760209160051b010190565b634e487b7160e01b600052603260045260246000fd5b9190916001600160801b03808094169116019182116132c457565b6001600160801b031691908215158061389f575b1561385a576006549161358483613383565b60805260008060a0525b6001600160801b0360a051168481101561375c5760005260056020526040600020546040519063133f757160e31b825260048201526101808160248173c36442b4a4522e871399cd717abdd847ab11fe885afa90811561375057600091829183808081829083928480968198829a613716575b506001600160801b038616156137045760a0516001600160801b031660005260056020526040600020549a6040519c8d9361363b856130e6565b6001600160601b03168452600160a01b60019003938480931690602001521660408d01521660608b015262ffffff1660808a0152600290810b60a08a01520b60c08801526001600160801b031660e08701526101008601526101208501526001600160801b03166101408401526001600160801b03166101608301526101808201526001600160801b0382169081608051906136d691613519565b52608051906136e491613519565b506136ee90613434565b935b6136fb60a051613434565b60a0529361358e565b505050505050505050505050936136f0565b9a505050505050505050505061373d91506101803d610180116110c4576110a6818361311d565b989a909791969295939493929138613601565b6040513d6000823e3d90fd5b509391925090600019016001600160801b0381116132c4578261377e916132ed565b6001600160801b0380821694168411613843576137a36001600160801b038416613383565b91600091825b608051516001600160801b0385169081101561383957878110158061381e575b156138135761380d916138016137e461380793608051613519565b516001600160801b038316906137fa828b613519565b5288613519565b50613434565b93613434565b926137a9565b509261380d90613434565b506001600160801b036138318885613543565b1681106137c9565b5050509250509150565b5091505060405161385381613102565b6000815290565b60405162461bcd60e51b815260206004820152601f60248201527f706167654e6f20616e642073697a652063616e206e6f74206265207a65726f006044820152606490fd5b506001600160801b0381161515613572565b670de0b6b3a7640000808202918083058214901517156132c45760405191635e2112d560e11b8352600483015260248201526706f05b59d3b2000060448201526020816064817316882fd345b2ed4e6578f538d7141af5702e6d4a5af490811561375057600091613999575b5068033dd1780914b9683f1981019081136001166132c457612710908082029180830582036132c45761138890661ec058ece91258809405071360001461398f5705600181019060006001831291129080158216911516176132c457603c905b60020b028060020b9081036132c45790565b90603c910561397d565b906020823d82116139c2575b816139b26020938361311d565b8101031261017c5750513861391d565b3d91506139a5565b3d156139f5573d906139db826131b3565b916139e9604051938461311d565b82523d6000602084013e565b606090565b90604051602081019163095ea7b360e01b835273c36442b4a4522e871399cd717abdd847ab11fe886024830152604482015260448152613a39816130cb565b600092839283809351925af190613a4e6139ca565b9082613ab7575b505015613a5e57565b60405162461bcd60e51b815260206004820152602b60248201527f5472616e7366657248656c7065723a3a73616665417070726f76653a2061707060448201526a1c9bdd994819985a5b195960aa1b6064820152608490fd5b9080925051918215928315613ad1575b5050503880613a55565b819293509060209181010312610a38576020015190811515820361017c5750388080613ac7565b604051602081019063095ea7b360e01b825273c36442b4a4522e871399cd717abdd847ab11fe886024820152600092839283838160448196015260448152613b3f816130cb565b51925af190613a4e6139ca565b6000808093819382604051613b6081613102565b525af1613b6b6139ca565b5015613b7357565b60405162461bcd60e51b815260206004820152603460248201527f5472616e7366657248656c7065723a3a736166655472616e736665724554483a60448201527308115512081d1c985b9cd9995c8819985a5b195960621b6064820152608490fdfe55f448fdea98c4d29eb340757ef0a66cd03dbb9538908a6a81d96026b71ec475c624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c15944998273e477b495144fb8794c914197f3ccb46be2900f4698fd0ef743c9695a2646970667358221220f683d87c74c36a78be93666759a0bc84116034d6efaa9516b4b5c566b2a8115364736f6c63430008120033

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
Loading...
Loading
[ Download: CSV Export  ]
[ 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.