ETH Price: $1,961.08 (-2.56%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Deposit Liquidit...207765962024-09-18 9:30:47529 days ago1726651847IN
0x5e7e2D40...21FDf0a57
0.2393 ETH0.0054484111.79790804
Deposit Liquidit...207765882024-09-18 9:29:11529 days ago1726651751IN
0x5e7e2D40...21FDf0a57
0.431 ETH0.0070577911.78282077
Deposit Liquidit...207765852024-09-18 9:28:35529 days ago1726651715IN
0x5e7e2D40...21FDf0a57
0.431 ETH0.0076948511.73149257
Deposit Liquidit...206896172024-09-06 5:59:23541 days ago1725602363IN
0x5e7e2D40...21FDf0a57
0 ETH0.000990861.58977168
Withdraw Liquidi...206896082024-09-06 5:57:35541 days ago1725602255IN
0x5e7e2D40...21FDf0a57
0 ETH0.00064411.52915887
Deposit Liquidit...206895772024-09-06 5:51:23541 days ago1725601883IN
0x5e7e2D40...21FDf0a57
0.001 ETH0.000905571.47051019
Withdraw Liquidi...206260272024-08-28 8:55:35550 days ago1724835335IN
0x5e7e2D40...21FDf0a57
0 ETH0.000580281.39484146
Deposit Liquidit...206257692024-08-28 8:03:35550 days ago1724832215IN
0x5e7e2D40...21FDf0a57
0.000001 ETH0.000907321.47361005
Claim Reward204890682024-08-09 5:51:47569 days ago1723182707IN
0x5e7e2D40...21FDf0a57
0 ETH0.000074421.15476358
Withdraw Liquidi...204890632024-08-09 5:50:47569 days ago1723182647IN
0x5e7e2D40...21FDf0a57
0 ETH0.000510811.24881644
Deposit Liquidit...204890602024-08-09 5:50:11569 days ago1723182611IN
0x5e7e2D40...21FDf0a57
0 ETH0.000849341.36445417
Deposit Liquidit...204890582024-08-09 5:49:47569 days ago1723182587IN
0x5e7e2D40...21FDf0a57
0 ETH0.000757911.38906638
Deposit Liquidit...204890562024-08-09 5:49:23569 days ago1723182563IN
0x5e7e2D40...21FDf0a57
0 ETH0.000806611.49526726
Deposit Liquidit...204890542024-08-09 5:48:59569 days ago1723182539IN
0x5e7e2D40...21FDf0a57
0.0001 ETH0.000689461.42997297
Deposit Liquidit...204890472024-08-09 5:47:35569 days ago1723182455IN
0x5e7e2D40...21FDf0a57
0.0001 ETH0.000706341.21046302
Deposit USDC For...204890462024-08-09 5:47:23569 days ago1723182443IN
0x5e7e2D40...21FDf0a57
0 ETH0.000613871.12351035
Deposit Liquidit...204760132024-08-07 10:11:23571 days ago1723025483IN
0x5e7e2D40...21FDf0a57
0.0001 ETH0.001146452.27202206
Withdraw Liquidi...204760012024-08-07 10:08:59571 days ago1723025339IN
0x5e7e2D40...21FDf0a57
0 ETH0.000722832.11823868
Deposit Liquidit...204759992024-08-07 10:08:23571 days ago1723025303IN
0x5e7e2D40...21FDf0a57
0 ETH0.001213282.00328219
Deposit Liquidit...204759962024-08-07 10:07:47571 days ago1723025267IN
0x5e7e2D40...21FDf0a57
0 ETH0.001225792.0551603
Deposit USDC For...204759942024-08-07 10:07:23571 days ago1723025243IN
0x5e7e2D40...21FDf0a57
0 ETH0.001470232.06012368
Deposit Liquidit...204759822024-08-07 10:04:59571 days ago1723025099IN
0x5e7e2D40...21FDf0a57
0.0001 ETH0.001285042.28429669
Deposit USDC For...204759812024-08-07 10:04:47571 days ago1723025087IN
0x5e7e2D40...21FDf0a57
0 ETH0.001667872.32043159
Deposit Liquidit...204758602024-08-07 9:40:35571 days ago1723023635IN
0x5e7e2D40...21FDf0a57
0.0001 ETH0.001614942.87623404
Deposit USDC For...204758592024-08-07 9:40:23571 days ago1723023623IN
0x5e7e2D40...21FDf0a57
0 ETH0.001924772.63090827
View all transactions

Latest 18 internal transactions

Advanced mode:
Parent Transaction Hash Method Block
From
To
Transfer*207765962024-09-18 9:30:47529 days ago1726651847
0x5e7e2D40...21FDf0a57
0.2393 ETH
Transfer*207765882024-09-18 9:29:11529 days ago1726651751
0x5e7e2D40...21FDf0a57
0.431 ETH
Transfer*207765852024-09-18 9:28:35529 days ago1726651715
0x5e7e2D40...21FDf0a57
0.431 ETH
Transfer*206895772024-09-06 5:51:23541 days ago1725601883
0x5e7e2D40...21FDf0a57
0.001 ETH
Transfer*206257692024-08-28 8:03:35550 days ago1724832215
0x5e7e2D40...21FDf0a57
0.000001 ETH
Transfer*204890542024-08-09 5:48:59569 days ago1723182539
0x5e7e2D40...21FDf0a57
0.0001 ETH
Transfer*204890472024-08-09 5:47:35569 days ago1723182455
0x5e7e2D40...21FDf0a57
0.0001 ETH
Transfer*204760132024-08-07 10:11:23571 days ago1723025483
0x5e7e2D40...21FDf0a57
0.0001 ETH
Transfer*204759822024-08-07 10:04:59571 days ago1723025099
0x5e7e2D40...21FDf0a57
0.0001 ETH
Transfer*204758602024-08-07 9:40:35571 days ago1723023635
0x5e7e2D40...21FDf0a57
0.0001 ETH
Transfer*204758122024-08-07 9:30:59571 days ago1723023059
0x5e7e2D40...21FDf0a57
0.0001 ETH
Transfer*204757692024-08-07 9:22:23571 days ago1723022543
0x5e7e2D40...21FDf0a57
0.0001 ETH
Transfer*204754342024-08-07 8:14:47571 days ago1723018487
0x5e7e2D40...21FDf0a57
0.000001 ETH
Transfer*204754162024-08-07 8:11:11571 days ago1723018271
0x5e7e2D40...21FDf0a57
0.0001 ETH
Transfer*204753712024-08-07 8:02:11571 days ago1723017731
0x5e7e2D40...21FDf0a57
0.0001 ETH
Transfer*204753622024-08-07 8:00:23571 days ago1723017623
0x5e7e2D40...21FDf0a57
0.0001 ETH
Transfer*204753282024-08-07 7:53:35571 days ago1723017215
0x5e7e2D40...21FDf0a57
0.0001 ETH
Transfer*204751652024-08-07 7:20:59571 days ago1723015259
0x5e7e2D40...21FDf0a57
0.0001 ETH
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Farm

Compiler Version
v0.8.18+commit.87f61d96

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./libraries/uniswapV3/LiquidityAmounts.sol";
import "./libraries/uniswapV3/TickMath.sol";
import "./interfaces/IFarmEvent.sol";
import "./interfaces/IStrategy.sol";
import "./interfaces/IStrategyInfo.sol";
import "./interfaces/uniswapV3/INonfungiblePositionManager.sol";
import "./interfaces/uniswapV3/IUniswapV3Pool.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "./interfaces/IConstants.sol";
import "./interfaces/IZap.sol";
import "./libraries/uniswapV3/TransferHelper.sol";

/// @dev verified, public contract
contract Farm is IFarmEvent {
    using SafeMath for uint256;

    IConstants public Constants;
    IZap public Zap;

    struct DepositInfo {
        uint128 increasedLiquidity;
        uint256 increasedShare;
        uint256 increasedToken0Amount;
        uint256 increasedToken1Amount;
        uint256 sendBackToken0Amount;
        uint256 sendBackToken1Amount;
    }

    constructor(address _constants, address _zap) {
        require(_constants != address(0), "Constants address cannot be zero");
        require(_zap != address(0), "Zap address cannot be zero");
        Constants = IConstants(_constants);
        Zap = IZap(_zap);
    }

    /// @dev deposit liquidity with one of the pair token
    /// @notice if isETH == true, user needs to transfer ETH to farm contract
    /// @notice if isETH == false, user needs to approve token to strategy contract
    function depositLiquidity(
        address _strategyContract,
        bool _isETH,
        address _inputToken,
        uint256 _inputAmount,
        uint256 _swapInAmount,
        uint256 _minimumSwapOutAmount
    ) public payable {
        require(!_isETH || msg.value == _inputAmount, "msg.value != _inputAmount");
        require(_isETH || msg.value == 0, "msg.value != 0");

        if (!_isETH) {
            TransferHelper.safeTransferFrom(_inputToken, msg.sender, address(this), _inputAmount);
            TransferHelper.safeApprove(_inputToken, _strategyContract, _inputAmount);
        }

        // DepositInfo struct: for avoiding stack too deep error
        DepositInfo memory depositInfo =
            executeDeposit(_strategyContract, _isETH, _inputToken, _inputAmount, _swapInAmount, _minimumSwapOutAmount);

        // Update share
        uint256 shareAfterDeposit = IStrategyInfo(_strategyContract).userShare(msg.sender);

        emit DepositLiquidity(
            _strategyContract,
            msg.sender,
            IStrategyInfo(_strategyContract).liquidityNftId(),
            _isETH,
            _inputToken,
            _inputAmount,
            shareAfterDeposit,
            depositInfo.increasedLiquidity,
            depositInfo.increasedShare,
            depositInfo.increasedToken0Amount,
            depositInfo.increasedToken1Amount,
            depositInfo.sendBackToken0Amount,
            depositInfo.sendBackToken1Amount
        );
    }

    function depositUSDCForLiquidity(
        address _strategyContract,
        address _inputToken,
        uint256 _inputAmount,
        uint256 _swapInAmount,
        uint256 _minimumSwapOutAmount
    ) public payable {
        require(msg.value == 0, "msg.value != 0");
        require(
            _inputToken == Constants.USDC_ADDRESS() || _inputToken == Constants.USDCE_ADDRESS(),
            "invalid USDC or USDC.e address"
        );

        (address token0, address token1) = getTokenAddresses(_strategyContract);

        // If input token is one of the pair token, call depositLiquidity function
        if (_inputToken == token0 || _inputToken == token1) {
            depositLiquidity(_strategyContract, false, _inputToken, _inputAmount, _swapInAmount, _minimumSwapOutAmount);
        } else {
            // If input token is not one of the pair token, using zap to swap for token0
            TransferHelper.safeTransferFrom(_inputToken, msg.sender, address(this), _inputAmount);
            TransferHelper.safeApprove(_inputToken, address(Zap), _inputAmount);

            uint256 depositInputAmount = Zap.swapToken(false, _inputToken, token0, _inputAmount, address(this));
            TransferHelper.safeApprove(token0, _strategyContract, depositInputAmount);

            // DepositInfo struct: for avoiding stack too deep error
            DepositInfo memory depositInfo = executeDeposit(
                _strategyContract, false, token0, depositInputAmount, _swapInAmount, _minimumSwapOutAmount
            );

            // Update share
            uint256 shareAfterDeposit = IStrategyInfo(_strategyContract).userShare(msg.sender);

            emit DepositLiquidity(
                _strategyContract,
                msg.sender,
                IStrategyInfo(_strategyContract).liquidityNftId(),
                false,
                _inputToken,
                _inputAmount,
                shareAfterDeposit,
                depositInfo.increasedLiquidity,
                depositInfo.increasedShare,
                depositInfo.increasedToken0Amount,
                depositInfo.increasedToken1Amount,
                depositInfo.sendBackToken0Amount,
                depositInfo.sendBackToken1Amount
            );
        }
    }

    function executeDeposit(
        address _strategyContract,
        bool _isETH,
        address _inputToken,
        uint256 _inputAmount,
        uint256 _swapInAmount,
        uint256 _minimumSwapOutAmount
    ) internal returns (DepositInfo memory depositInfo) {
        (
            depositInfo.increasedLiquidity,
            depositInfo.increasedShare,
            depositInfo.increasedToken0Amount,
            depositInfo.increasedToken1Amount,
            depositInfo.sendBackToken0Amount,
            depositInfo.sendBackToken1Amount
        ) = IStrategy(_strategyContract).depositLiquidity{value: _isETH ? _inputAmount : 0}(
            _isETH, msg.sender, _inputToken, _inputAmount, _swapInAmount, _minimumSwapOutAmount
        );
    }

    function getTokenAddresses(address strategyAddress) internal view returns (address token0, address token1) {
        token0 = IStrategyInfo(strategyAddress).token0Address();
        token1 = IStrategyInfo(strategyAddress).token1Address();
    }

    /// @dev withdraw liquidity
    /// @notice user needs to approve tracker token to strategy contract in withdrawShares amount
    function withdrawLiquidity(address _strategyContract, uint256 _withdrawShares) public {
        (uint256 userReceivedToken0Amount, uint256 userReceivedToken1Amount) =
            IStrategy(_strategyContract).withdrawLiquidity(msg.sender, _withdrawShares);

        emit WithdrawLiquidity(
            _strategyContract,
            msg.sender,
            IStrategyInfo(_strategyContract).liquidityNftId(),
            _withdrawShares,
            IStrategyInfo(_strategyContract).userShare(msg.sender),
            userReceivedToken0Amount,
            userReceivedToken1Amount
        );
    }

    /// @dev claim wbtc reward
    function claimReward(address _strategyContract) public {
        uint256 claimedRewardAmount = IStrategyInfo(_strategyContract).userDistributeReward(msg.sender);
        IStrategy(_strategyContract).claimReward(msg.sender);

        emit ClaimReward(
            _strategyContract, msg.sender, IStrategyInfo(_strategyContract).liquidityNftId(), claimedRewardAmount
        );
    }

    /// @dev get estimate deposit used amount
    function getEstimatedUsedDepositToken(address _strategyContract, uint256 _depositAmount0, uint256 _depositAmount1)
        public
        view
        returns (uint256 estimatedUsedAmount0, uint256 estimatedUsedAmount1)
    {
        // get tick, tickUpper, tickLower sprt price
        (uint160 sqrtPriceX96, uint160 sqrtRatioAX96, uint160 sqrtRatioBX96) = getSqrtPriceInfo(_strategyContract);

        uint128 estimatedLiquidity = LiquidityAmounts.getLiquidityForAmounts(
            sqrtPriceX96, sqrtRatioAX96, sqrtRatioBX96, _depositAmount0, _depositAmount1
        );

        (estimatedUsedAmount0, estimatedUsedAmount1) =
            LiquidityAmounts.getAmountsForLiquidity(sqrtPriceX96, sqrtRatioAX96, sqrtRatioBX96, estimatedLiquidity);
    }

    function getSqrtPriceInfo(address _strategyContract)
        internal
        view
        returns (uint160 sqrtPriceX96, uint160 sqrtRatioAX96, uint160 sqrtRatioBX96)
    {
        // get poolAddress
        address poolAddress = IStrategyInfo(_strategyContract).poolAddress();

        // get tick
        (, int24 tick,,,,,) = IUniswapV3Pool(poolAddress).slot0();

        // get tickUpper & tickLower
        uint256 liquidityNftId = IStrategyInfo(_strategyContract).liquidityNftId();

        require(liquidityNftId != 0, "not allow calling when liquidityNftId is 0");

        (,,,,, int24 tickLower, int24 tickUpper,,,,,) =
            INonfungiblePositionManager(Constants.NONFUNGIBLE_POSITION_MANAGER_ADDRESS()).positions(liquidityNftId);

        // calculate sqrtPrice
        sqrtPriceX96 = TickMath.getSqrtRatioAtTick(tick);
        sqrtRatioAX96 = TickMath.getSqrtRatioAtTick(tickLower);
        sqrtRatioBX96 = TickMath.getSqrtRatioAtTick(tickUpper);
    }

    function getUserShare(address _strategyContract, address _userAddress) public view returns (uint256 userShare) {
        return IStrategyInfo(_strategyContract).userShare(_userAddress);
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 amount) external returns (bool);
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol)

pragma solidity ^0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        return a * b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        unchecked {
            require(b <= a, errorMessage);
            return a - b;
        }
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a / b;
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

interface IConstants {
    /// @dev Uniswap v3 Related
    function UNISWAP_V3_FACTORY_ADDRESS() external view returns (address);
    function NONFUNGIBLE_POSITION_MANAGER_ADDRESS() external view returns (address);
    function SWAP_ROUTER_ADDRESS() external view returns (address);

    /// @dev Distribute reward token address
    function DISTRIBUTE_REWARD_ADDRESS() external view returns (address);

    /// @dev Token address (combine each chain)
    function WETH_ADDRESS() external view returns (address);
    function WBTC_ADDRESS() external view returns (address);
    function ARB_ADDRESS() external view returns (address);
    function USDC_ADDRESS() external view returns (address);
    function USDCE_ADDRESS() external view returns (address);
    function USDT_ADDRESS() external view returns (address);
    function RDNT_ADDRESS() external view returns (address);
    function LINK_ADDRESS() external view returns (address);
    function DEGEN_ADDRESS() external view returns (address);
    function BRETT_ADDRESS() external view returns (address);
    function TOSHI_ADDRESS() external view returns (address);
    function CIRCLE_ADDRESS() external view returns (address);
    function ROOST_ADDRESS() external view returns (address);
    function AERO_ADDRESS() external view returns (address);
    function INT_ADDRESS() external view returns (address);
    function HIGHER_ADDRESS() external view returns (address);
    function KEYCAT_ADDRESS() external view returns (address);

    /// @dev Black hole address
    function BLACK_HOLE_ADDRESS() external view returns (address);
}

File 5 of 15 : IFarmEvent.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

interface IFarmEvent {
    event DepositLiquidity(
        address indexed strategyContract,
        address indexed userAddress,
        uint256 indexed liquidityNftId,
        bool isETH,
        address inputToken,
        uint256 inputAmount,
        uint256 userShareAfterDeposit,
        uint128 increasedLiquidity,
        uint256 increasedShare,
        uint256 increasedToken0Amount,
        uint256 increasedToken1Amount,
        uint256 sendBackToken0Amount,
        uint256 sendBackToken1Amount
    );

    event WithdrawLiquidity(
        address indexed strategyContract,
        address indexed userAddress,
        uint256 indexed liquidityNftId,
        uint256 decreasedShare,
        uint256 userShareAfterWithdraw,
        uint256 userReceivedToken0Amount,
        uint256 userReceivedToken1Amount
    );

    event ClaimReward(
        address indexed strategyContract,
        address indexed userAddress,
        uint256 indexed liquidityNftId,
        uint256 claimedRewardAmount
    );
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

interface IStrategy {
    function depositLiquidity(
        bool isETH,
        address userAddress,
        address inputToken,
        uint256 inputAmount,
        uint256 swapInAmount,
        uint256 minimumSwapOutAmount
    )
        external
        payable
        returns (
            uint128 increasedLiquidity,
            uint256 increasedShare,
            uint256 increasedToken0Amount,
            uint256 increasedToken1Amount,
            uint256 sendBackToken0Amount,
            uint256 sendBackToken1Amount
        );

    function withdrawLiquidity(address userAddress, uint256 withdrawShares)
        external
        returns (uint256 userReceivedToken0Amount, uint256 userReceivedToken1Amount);

    function collectRewards() external;

    function earnPreparation(
        uint256 minimumToken0SwapOutAmount,
        uint256 minimumToken1SwapOutAmount,
        uint256 minimumBuybackSwapOutAmount
    ) external;

    function earn() external;

    function claimReward(address userAddress) external;

    function rescale(int24 newTickUpper, int24 newTickLower) external;

    function depositDustToken(bool depositDustToken0)
        external
        returns (uint256 increasedToken0Amount, uint256 increasedToken1Amount);

    function updateZapContract(address newZapContract) external;
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

interface IStrategyInfo {
    /// @dev Uniswap-Transaction-related Variable
    function transactionDeadlineDuration() external view returns (uint256);

    /// @dev get Liquidity-NFT-related Variable
    function liquidityNftId() external view returns (uint256);

    function tickSpacing() external view returns (int24);

    /// @dev get Pool-related Variable
    function poolAddress() external view returns (address);

    function poolFee() external view returns (uint24);

    function token0Address() external view returns (address);

    function token1Address() external view returns (address);

    /// @dev get Tracker-Token-related Variable
    function trackerTokenAddress() external view returns (address);

    /// @dev get User-Management-related Variable
    function isInUserList(address userAddress) external view returns (bool);

    function userIndex(address userAddress) external view returns (uint256);

    function getAllUsersInUserList() external view returns (address[] memory);

    /// @dev get User-Share-Management-related Variable
    function userShare(address userAddress) external view returns (uint256);

    function totalUserShare() external view returns (uint256);

    /// @dev get Reward-Management-related Variable
    function rewardToken0Amount() external view returns (uint256);

    function rewardToken1Amount() external view returns (uint256);

    function distributeRewardAmount() external view returns (uint256);

    /// @dev get User-Reward-Management-related Variable
    function userDistributeReward(address userAddress) external view returns (uint256);

    function totalUserDistributeReward() external view returns (uint256);

    /// @dev get Buyback-related Variable
    function buyBackToken() external view returns (address);

    function buyBackNumerator() external view returns (uint24);

    /// @dev get Fund-Manager-related Variable
    struct FundManagerVault {
        address fundManagerVaultAddress;
        uint256 fundManagerProfitVaultNumerator;
    }

    function getAllFundManagerVaults() external view returns (FundManagerVault[3] memory);

    /// @dev get Earn-Loop-Control-related Variable
    function earnLoopSegmentSize() external view returns (uint256);

    function earnLoopDistributedAmount() external view returns (uint256);

    function earnLoopStartIndex() external view returns (uint256);

    function isEarning() external view returns (bool);

    /// @dev get Rescale-related Variable
    function dustToken0Amount() external view returns (uint256);

    function dustToken1Amount() external view returns (uint256);

    /// @dev get Constant Variable
    function getBuyBackDenominator() external pure returns (uint24);

    function getFundManagerProfitVaultDenominator() external pure returns (uint24);

    function getFarmAddress() external view returns (address);

    function getControllerAddress() external view returns (address);

    function getSwapAmountCalculatorAddress() external view returns (address);

    function getZapAddress() external view returns (address);
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

interface IZap {
    /// @dev get zap data
    function slippageToleranceNumerator() external view returns (uint24);

    function getSwapInfo(address inputToken, address outputToken)
        external
        view
        returns (bool isPathDefined, address[] memory swapPathArray, uint24[] memory swapTradeFeeArray);

    function getTokenExchangeRate(address inputToken, address outputToken)
        external
        view
        returns (address token0, address token1, uint256 tokenPriceWith18Decimals);

    function getMinimumSwapOutAmount(address inputToken, address outputToken, uint256 inputAmount)
        external
        view
        returns (uint256 minimumSwapOutAmount);

    /// @dev swapToken
    function swapToken(bool isETH, address inputToken, address outputToken, uint256 inputAmount, address recipient)
        external
        payable
        returns (uint256 outputAmount);

    function swapTokenWithMinimumOutput(
        bool isETH,
        address inputToken,
        address outputToken,
        uint256 inputAmount,
        uint256 minimumSwapOutAmount,
        address recipient
    ) external payable returns (uint256 outputAmount);
}

// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.7.5;
pragma abicoder v2;

interface INonfungiblePositionManager {
    /// @notice Returns the position information associated with a given token ID.
    /// @dev Throws if the token ID is not valid.
    /// @param tokenId The ID of the token that represents the position
    /// @return nonce The nonce for permits
    /// @return operator The address that is approved for spending
    /// @return token0 The address of the token0 for a specific pool
    /// @return token1 The address of the token1 for a specific pool
    /// @return fee The fee associated with the pool
    /// @return tickLower The lower end of the tick range for the position
    /// @return tickUpper The higher end of the tick range for the position
    /// @return liquidity The liquidity of the position
    /// @return feeGrowthInside0LastX128 The fee growth of token0 as of the last action on the individual position
    /// @return feeGrowthInside1LastX128 The fee growth of token1 as of the last action on the individual position
    /// @return tokensOwed0 The uncollected amount of token0 owed to the position as of the last computation
    /// @return tokensOwed1 The uncollected amount of token1 owed to the position as of the last computation
    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
        );

    /// @notice Refunds any ETH balance held by this contract to the `msg.sender`
    /// @dev Useful for bundling with mint or increase liquidity that uses ether, or exact output swaps
    /// that use ether for the input amount
    function refundETH() external payable;

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

    /// @notice Creates a new position wrapped in a NFT
    /// @dev Call this when the pool does exist and is initialized. Note that if the pool is created but not initialized
    /// a method does not exist, i.e. the pool is assumed to be initialized.
    /// @param params The params necessary to mint a position, encoded as `MintParams` in calldata
    /// @return tokenId The ID of the token that represents the minted position
    /// @return liquidity The amount of liquidity for this position
    /// @return amount0 The amount of token0
    /// @return amount1 The amount of token1
    function mint(
        MintParams calldata params
    )
        external
        payable
        returns (
            uint256 tokenId,
            uint128 liquidity,
            uint256 amount0,
            uint256 amount1
        );

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

    /// @notice Increases the amount of liquidity in a position, with tokens paid by the `msg.sender`
    /// @param params tokenId The ID of the token for which liquidity is being increased,
    /// amount0Desired The desired amount of token0 to be spent,
    /// amount1Desired The desired amount of token1 to be spent,
    /// amount0Min The minimum amount of token0 to spend, which serves as a slippage check,
    /// amount1Min The minimum amount of token1 to spend, which serves as a slippage check,
    /// deadline The time by which the transaction must be included to effect the change
    /// @return liquidity The new liquidity amount as a result of the increase
    /// @return amount0 The amount of token0 to acheive resulting liquidity
    /// @return amount1 The amount of token1 to acheive resulting liquidity
    function increaseLiquidity(
        IncreaseLiquidityParams calldata params
    )
        external
        payable
        returns (uint128 liquidity, uint256 amount0, uint256 amount1);

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

    /// @notice Decreases the amount of liquidity in a position and accounts it to the position
    /// @param params tokenId The ID of the token for which liquidity is being decreased,
    /// amount The amount by which liquidity will be decreased,
    /// amount0Min The minimum amount of token0 that should be accounted for the burned liquidity,
    /// amount1Min The minimum amount of token1 that should be accounted for the burned liquidity,
    /// deadline The time by which the transaction must be included to effect the change
    /// @return amount0 The amount of token0 accounted to the position's tokens owed
    /// @return amount1 The amount of token1 accounted to the position's tokens owed
    function decreaseLiquidity(
        DecreaseLiquidityParams calldata params
    ) external payable returns (uint256 amount0, uint256 amount1);

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

    /// @notice Collects up to a maximum amount of fees owed to a specific position to the recipient
    /// @param params tokenId The ID of the NFT for which tokens are being collected,
    /// recipient The account that should receive the tokens,
    /// amount0Max The maximum amount of token0 to collect,
    /// amount1Max The maximum amount of token1 to collect
    /// @return amount0 The amount of fees collected in token0
    /// @return amount1 The amount of fees collected in token1
    function collect(
        CollectParams calldata params
    ) external payable returns (uint256 amount0, uint256 amount1);

    /// @notice Burns a token ID, which deletes it from the NFT contract. The token must have 0 liquidity and all tokens
    /// must be collected first.
    /// @param tokenId The ID of the token that is being burned
    function burn(uint256 tokenId) external payable;
}

// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.5.0;

interface IUniswapV3Pool {
    /// @notice The 0th storage slot in the pool stores many values, and is exposed as a single method to save gas
    /// when accessed externally.
    /// @return sqrtPriceX96 The current price of the pool as a sqrt(token1/token0) Q64.96 value
    /// tick The current tick of the pool, i.e. according to the last tick transition that was run.
    /// This value may not always be equal to SqrtTickMath.getTickAtSqrtRatio(sqrtPriceX96) if the price is on a tick
    /// boundary.
    /// observationIndex The index of the last oracle observation that was written,
    /// observationCardinality The current maximum number of observations stored in the pool,
    /// observationCardinalityNext The next maximum number of observations, to be updated when the observation.
    /// feeProtocol The protocol fee for both tokens of the pool.
    /// Encoded as two 4 bit values, where the protocol fee of token1 is shifted 4 bits and the protocol fee of token0
    /// is the lower 4 bits. Used as the denominator of a fraction of the swap fee, e.g. 4 means 1/4th of the swap fee.
    /// unlocked Whether the pool is currently locked to reentrancy
    function slot0()
        external
        view
        returns (
            uint160 sqrtPriceX96,
            int24 tick,
            uint16 observationIndex,
            uint16 observationCardinality,
            uint16 observationCardinalityNext,
            uint8 feeProtocol,
            bool unlocked
        );

    /// @notice The first of the two tokens of the pool, sorted by address
    /// @return The token contract address
    function token0() external view returns (address);

    /// @notice The second of the two tokens of the pool, sorted by address
    /// @return The token contract address
    function token1() external view returns (address);

    /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6
    /// @return The fee
    function fee() external view returns (uint24);

    /// @notice The pool tick spacing
    /// @dev Ticks can only be used at multiples of this value, minimum of 1 and always positive
    /// e.g.: a tickSpacing of 3 means ticks can be initialized every 3rd tick, i.e., ..., -6, -3, 0, 3, 6, ...
    /// This value is an int24 to avoid casting even though it is always positive.
    /// @return The tick spacing
    function tickSpacing() external view returns (int24);
}

File 11 of 15 : FixedPoint96.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.4.0;

/// @title FixedPoint96
/// @notice A library for handling binary fixed point numbers, see https://en.wikipedia.org/wiki/Q_(number_format)
/// @dev Used in SqrtPriceMath.sol
library FixedPoint96 {
    uint8 internal constant RESOLUTION = 96;
    uint256 internal constant Q96 = 0x1000000000000000000000000;
}

// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;

/// @title Contains 512-bit math functions
/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision
/// @dev Handles "phantom overflow" i.e., allows multiplication and division where an intermediate value overflows 256 bits
library FullMath {
    /// @notice Calculates floor(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
    /// @param a The multiplicand
    /// @param b The multiplier
    /// @param denominator The divisor
    /// @return result The 256-bit result
    /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv
    function mulDiv(
        uint256 a,
        uint256 b,
        uint256 denominator
    ) internal pure returns (uint256 result) {
        // 512-bit multiply [prod1 prod0] = a * b
        // Compute the product mod 2**256 and mod 2**256 - 1
        // then use the Chinese Remainder Theorem to reconstruct
        // the 512 bit result. The result is stored in two 256
        // variables such that product = prod1 * 2**256 + prod0
        uint256 prod0; // Least significant 256 bits of the product
        uint256 prod1; // Most significant 256 bits of the product
        assembly {
            let mm := mulmod(a, b, not(0))
            prod0 := mul(a, b)
            prod1 := sub(sub(mm, prod0), lt(mm, prod0))
        }

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

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

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

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

        // Factor powers of two out of denominator
        // Compute largest power of two divisor of denominator.
        // Always >= 1.
        uint256 twos = (~denominator) + 1;
        // Divide denominator by power of two
        assembly {
            denominator := div(denominator, twos)
        }

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

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

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

    /// @notice Calculates ceil(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
    /// @param a The multiplicand
    /// @param b The multiplier
    /// @param denominator The divisor
    /// @return result The 256-bit result
    function mulDivRoundingUp(
        uint256 a,
        uint256 b,
        uint256 denominator
    ) internal pure returns (uint256 result) {
        result = mulDiv(a, b, denominator);
        if (mulmod(a, b, denominator) > 0) {
            require(result < type(uint256).max);
            result++;
        }
    }
}

// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.5.0;

import "./FullMath.sol";
import "./FixedPoint96.sol";

/// @title Liquidity amount functions
/// @notice Provides functions for computing liquidity amounts from token amounts and prices
library LiquidityAmounts {
    /// @notice Downcasts uint256 to uint128
    /// @param x The uint258 to be downcasted
    /// @return y The passed value, downcasted to uint128
    function toUint128(uint256 x) private pure returns (uint128 y) {
        require((y = uint128(x)) == x);
    }

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

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

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

        if (sqrtRatioX96 <= sqrtRatioAX96) {
            liquidity = getLiquidityForAmount0(
                sqrtRatioAX96,
                sqrtRatioBX96,
                amount0
            );
        } else if (sqrtRatioX96 < sqrtRatioBX96) {
            uint128 liquidity0 = getLiquidityForAmount0(
                sqrtRatioX96,
                sqrtRatioBX96,
                amount0
            );
            uint128 liquidity1 = getLiquidityForAmount1(
                sqrtRatioAX96,
                sqrtRatioX96,
                amount1
            );

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

    /// @notice Computes the amount of token0 for a given amount of liquidity and a price range
    /// @param sqrtRatioAX96 A sqrt price representing the first tick boundary
    /// @param sqrtRatioBX96 A sqrt price representing the second tick boundary
    /// @param liquidity The liquidity being valued
    /// @return amount0 The amount of token0
    function getAmount0ForLiquidity(
        uint160 sqrtRatioAX96,
        uint160 sqrtRatioBX96,
        uint128 liquidity
    ) internal pure returns (uint256 amount0) {
        if (sqrtRatioAX96 > sqrtRatioBX96)
            (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);

        uint256 originalResult = FullMath.mulDiv(
            uint256(liquidity) << FixedPoint96.RESOLUTION,
            sqrtRatioBX96 - sqrtRatioAX96,
            sqrtRatioBX96
        ) / sqrtRatioAX96;

        /// @dev handle overflow issue
        if (originalResult != 0) {
            return originalResult;
        } else {
            return
                FullMath.mulDiv(
                    (uint256(liquidity) << FixedPoint96.RESOLUTION) /
                        sqrtRatioAX96,
                    sqrtRatioBX96 - sqrtRatioAX96,
                    sqrtRatioBX96
                );
        }
    }

    /// @notice Computes the amount of token1 for a given amount of liquidity and a price range
    /// @param sqrtRatioAX96 A sqrt price representing the first tick boundary
    /// @param sqrtRatioBX96 A sqrt price representing the second tick boundary
    /// @param liquidity The liquidity being valued
    /// @return amount1 The amount of token1
    function getAmount1ForLiquidity(
        uint160 sqrtRatioAX96,
        uint160 sqrtRatioBX96,
        uint128 liquidity
    ) internal pure returns (uint256 amount1) {
        if (sqrtRatioAX96 > sqrtRatioBX96)
            (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);

        return
            FullMath.mulDiv(
                liquidity,
                sqrtRatioBX96 - sqrtRatioAX96,
                FixedPoint96.Q96
            );
    }

    /// @notice Computes the token0 and token1 value for a given amount of liquidity, the current
    /// pool prices and the prices at the tick boundaries
    /// @param sqrtRatioX96 A sqrt price representing the current pool prices
    /// @param sqrtRatioAX96 A sqrt price representing the first tick boundary
    /// @param sqrtRatioBX96 A sqrt price representing the second tick boundary
    /// @param liquidity The liquidity being valued
    /// @return amount0 The amount of token0
    /// @return amount1 The amount of token1
    function getAmountsForLiquidity(
        uint160 sqrtRatioX96,
        uint160 sqrtRatioAX96,
        uint160 sqrtRatioBX96,
        uint128 liquidity
    ) internal pure returns (uint256 amount0, uint256 amount1) {
        if (sqrtRatioAX96 > sqrtRatioBX96)
            (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);

        if (sqrtRatioX96 <= sqrtRatioAX96) {
            amount0 = getAmount0ForLiquidity(
                sqrtRatioAX96,
                sqrtRatioBX96,
                liquidity
            );
        } else if (sqrtRatioX96 < sqrtRatioBX96) {
            amount0 = getAmount0ForLiquidity(
                sqrtRatioX96,
                sqrtRatioBX96,
                liquidity
            );
            amount1 = getAmount1ForLiquidity(
                sqrtRatioAX96,
                sqrtRatioX96,
                liquidity
            );
        } else {
            amount1 = getAmount1ForLiquidity(
                sqrtRatioAX96,
                sqrtRatioBX96,
                liquidity
            );
        }
    }
}

// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.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));
        require(absTick <= uint256(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)
        );
    }
}

// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.6.0;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

library TransferHelper {
    /// @notice Transfers tokens from the targeted address to the given destination
    /// @notice Errors with 'STF' if transfer fails
    /// @param token The contract address of the token to be transferred
    /// @param from The originating address from which the tokens will be transferred
    /// @param to The destination address of the transfer
    /// @param value The amount to be transferred
    function safeTransferFrom(address token, address from, address to, uint256 value) internal {
        (bool success, bytes memory data) =
            token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value));

        require(success && (data.length == 0 || abi.decode(data, (bool))), "STF");
    }

    /// @notice Transfers tokens from msg.sender to a recipient
    /// @dev Errors with ST if transfer fails
    /// @param token The contract address of the token which will be transferred
    /// @param to The recipient of the transfer
    /// @param value The value of the transfer
    function safeTransfer(address token, address to, uint256 value) internal {
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), "ST");
    }

    /// @notice Approves the stipulated contract to spend the given allowance in the given token
    /// @dev Errors with 'SA' if transfer fails
    /// @param token The contract address of the token to be approved
    /// @param to The target of the approval
    /// @param value The amount of the given token the target will be allowed to spend
    function safeApprove(address token, address to, uint256 value) internal {
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.approve.selector, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), "SA");
    }

    /// @notice Transfers ETH to the recipient address
    /// @dev Fails with `STE`
    /// @param to The destination of the transfer
    /// @param value The value to be transferred
    function safeTransferETH(address to, uint256 value) internal {
        (bool success,) = to.call{value: value}(new bytes(0));
        require(success, "STE");
    }
}

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

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_constants","type":"address"},{"internalType":"address","name":"_zap","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategyContract","type":"address"},{"indexed":true,"internalType":"address","name":"userAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"liquidityNftId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"claimedRewardAmount","type":"uint256"}],"name":"ClaimReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategyContract","type":"address"},{"indexed":true,"internalType":"address","name":"userAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"liquidityNftId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isETH","type":"bool"},{"indexed":false,"internalType":"address","name":"inputToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"inputAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"userShareAfterDeposit","type":"uint256"},{"indexed":false,"internalType":"uint128","name":"increasedLiquidity","type":"uint128"},{"indexed":false,"internalType":"uint256","name":"increasedShare","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"increasedToken0Amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"increasedToken1Amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"sendBackToken0Amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"sendBackToken1Amount","type":"uint256"}],"name":"DepositLiquidity","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategyContract","type":"address"},{"indexed":true,"internalType":"address","name":"userAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"liquidityNftId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"decreasedShare","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"userShareAfterWithdraw","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"userReceivedToken0Amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"userReceivedToken1Amount","type":"uint256"}],"name":"WithdrawLiquidity","type":"event"},{"inputs":[],"name":"Constants","outputs":[{"internalType":"contract IConstants","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"Zap","outputs":[{"internalType":"contract IZap","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_strategyContract","type":"address"}],"name":"claimReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategyContract","type":"address"},{"internalType":"bool","name":"_isETH","type":"bool"},{"internalType":"address","name":"_inputToken","type":"address"},{"internalType":"uint256","name":"_inputAmount","type":"uint256"},{"internalType":"uint256","name":"_swapInAmount","type":"uint256"},{"internalType":"uint256","name":"_minimumSwapOutAmount","type":"uint256"}],"name":"depositLiquidity","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategyContract","type":"address"},{"internalType":"address","name":"_inputToken","type":"address"},{"internalType":"uint256","name":"_inputAmount","type":"uint256"},{"internalType":"uint256","name":"_swapInAmount","type":"uint256"},{"internalType":"uint256","name":"_minimumSwapOutAmount","type":"uint256"}],"name":"depositUSDCForLiquidity","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategyContract","type":"address"},{"internalType":"uint256","name":"_depositAmount0","type":"uint256"},{"internalType":"uint256","name":"_depositAmount1","type":"uint256"}],"name":"getEstimatedUsedDepositToken","outputs":[{"internalType":"uint256","name":"estimatedUsedAmount0","type":"uint256"},{"internalType":"uint256","name":"estimatedUsedAmount1","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_strategyContract","type":"address"},{"internalType":"address","name":"_userAddress","type":"address"}],"name":"getUserShare","outputs":[{"internalType":"uint256","name":"userShare","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_strategyContract","type":"address"},{"internalType":"uint256","name":"_withdrawShares","type":"uint256"}],"name":"withdrawLiquidity","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b506040516200228038038062002280833981016040819052620000349162000137565b6001600160a01b038216620000905760405162461bcd60e51b815260206004820181905260248201527f436f6e7374616e747320616464726573732063616e6e6f74206265207a65726f60448201526064015b60405180910390fd5b6001600160a01b038116620000e85760405162461bcd60e51b815260206004820152601a60248201527f5a617020616464726573732063616e6e6f74206265207a65726f000000000000604482015260640162000087565b600080546001600160a01b039384166001600160a01b031991821617909155600180549290931691161790556200016f565b80516001600160a01b03811681146200013257600080fd5b919050565b600080604083850312156200014b57600080fd5b62000156836200011a565b915062000166602084016200011a565b90509250929050565b612101806200017f6000396000f3fe60806040526004361061007b5760003560e01c8063d279c1911161004e578063d279c19114610120578063d85bb20514610140578063e231f7d514610153578063fafc80991461018857600080fd5b806306d47de9146100805780631bf840c1146100a25780635cb7d1f4146100d5578063b35924a11461010d575b600080fd5b34801561008c57600080fd5b506100a061009b366004611b3b565b6101a8565b005b3480156100ae57600080fd5b506100c26100bd366004611b67565b610340565b6040519081526020015b60405180910390f35b3480156100e157600080fd5b506000546100f5906001600160a01b031681565b6040516001600160a01b0390911681526020016100cc565b6100a061011b366004611bae565b6103b7565b34801561012c57600080fd5b506100a061013b366004611c13565b6105d8565b6100a061014e366004611c30565b610745565b34801561015f57600080fd5b5061017361016e366004611c81565b610b68565b604080519283526020830191909152016100cc565b34801561019457600080fd5b506001546100f5906001600160a01b031681565b6040516306d47de960e01b81523360048201526024810182905260009081906001600160a01b038516906306d47de99060440160408051808303816000875af11580156101f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061021d9190611cb6565b91509150836001600160a01b031663ead892be6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561025f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102839190611cda565b6040516303c4f78760e51b81523360048201819052906001600160a01b038716907fceee31e29d568de062f944bd6ff828723e2e4c3590ef604b5370647249800469908790839063789ef0e090602401602060405180830381865afa1580156102f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103149190611cda565b60408051928352602083019190915281018790526060810186905260800160405180910390a450505050565b6040516303c4f78760e51b81526001600160a01b0382811660048301526000919084169063789ef0e090602401602060405180830381865afa15801561038a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103ae9190611cda565b90505b92915050565b8415806103c357508234145b6104145760405162461bcd60e51b815260206004820152601960248201527f6d73672e76616c756520213d205f696e707574416d6f756e740000000000000060448201526064015b60405180910390fd5b848061041e575034155b61045b5760405162461bcd60e51b815260206004820152600e60248201526d06d73672e76616c756520213d20360941b604482015260640161040b565b846104775761046c84333086610bac565b610477848785610cb6565b6000610487878787878787610db6565b6040516303c4f78760e51b81523360048201529091506000906001600160a01b0389169063789ef0e090602401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f59190611cda565b9050876001600160a01b031663ead892be6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610535573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105599190611cda565b336001600160a01b0316896001600160a01b03167fd5a9f37d804ba98f2d513a8ebca817086cd1060534f07c44eb012c8a492c051f8a8a8a8789600001518a602001518b604001518c606001518d608001518e60a001516040516105c69a99989796959493929190611cf3565b60405180910390a45050505050505050565b604051637a1cdbcf60e01b81523360048201526000906001600160a01b03831690637a1cdbcf90602401602060405180830381865afa15801561061f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106439190611cda565b60405163d279c19160e01b81523360048201529091506001600160a01b0383169063d279c19190602401600060405180830381600087803b15801561068757600080fd5b505af115801561069b573d6000803e3d6000fd5b50505050816001600160a01b031663ead892be6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107019190611cda565b60405182815233906001600160a01b038516907ffe7c5fc89da23a432c91f264decb100ab9d08ab7b14650c3cdb9b6b4f84a60e99060200160405180910390a45050565b34156107845760405162461bcd60e51b815260206004820152600e60248201526d06d73672e76616c756520213d20360941b604482015260640161040b565b60008054906101000a90046001600160a01b03166001600160a01b031663bb09d9b76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107f99190611d57565b6001600160a01b0316846001600160a01b0316148061089d575060008054906101000a90046001600160a01b03166001600160a01b03166341104a226040518163ffffffff1660e01b8152600401602060405180830381865afa158015610864573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108889190611d57565b6001600160a01b0316846001600160a01b0316145b6108e95760405162461bcd60e51b815260206004820152601e60248201527f696e76616c69642055534443206f7220555344432e6520616464726573730000604482015260640161040b565b6000806108f587610ecf565b91509150816001600160a01b0316866001600160a01b0316148061092a5750806001600160a01b0316866001600160a01b0316145b156109435761093e876000888888886103b7565b610b5f565b61094f86333088610bac565b6001546109679087906001600160a01b031687610cb6565b600154604051633b4cdc4360e01b81526000600482018190526001600160a01b03898116602484015285811660448401526064830189905230608484015290921690633b4cdc439060a4016020604051808303816000875af11580156109d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109f59190611cda565b9050610a02838983610cb6565b6000610a1389600086858a8a610db6565b6040516303c4f78760e51b81523360048201529091506000906001600160a01b038b169063789ef0e090602401602060405180830381865afa158015610a5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a819190611cda565b9050896001600160a01b031663ead892be6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ac1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ae59190611cda565b336001600160a01b03168b6001600160a01b03167fd5a9f37d804ba98f2d513a8ebca817086cd1060534f07c44eb012c8a492c051f60008d8d8789600001518a602001518b604001518c606001518d608001518e60a00151604051610b539a99989796959493929190611cf3565b60405180910390a45050505b50505050505050565b6000806000806000610b7988610f9f565b9250925092506000610b8e8484848b8b611255565b9050610b9c84848484611319565b909a909950975050505050505050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b1790529151600092839290881691610c109190611d74565b6000604051808303816000865af19150503d8060008114610c4d576040519150601f19603f3d011682016040523d82523d6000602084013e610c52565b606091505b5091509150818015610c7c575080511580610c7c575080806020019051810190610c7c9190611da3565b610cae5760405162461bcd60e51b815260206004820152600360248201526229aa2360e91b604482015260640161040b565b505050505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663095ea7b360e01b1790529151600092839290871691610d129190611d74565b6000604051808303816000865af19150503d8060008114610d4f576040519150601f19603f3d011682016040523d82523d6000602084013e610d54565b606091505b5091509150818015610d7e575080511580610d7e575080806020019051810190610d7e9190611da3565b610daf5760405162461bcd60e51b8152602060048201526002602482015261534160f01b604482015260640161040b565b5050505050565b610df86040518060c0016040528060006001600160801b0316815260200160008152602001600081526020016000815260200160008152602001600081525090565b866001600160a01b031663d9933d5a87610e13576000610e15565b855b6040516001600160e01b031960e084901b16815289151560048201523360248201526001600160a01b0389166044820152606481018890526084810187905260a4810186905260c40160c06040518083038185885af1158015610e7c573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610ea19190611dd7565b60a087015260808601526060850152604084015260208301526001600160801b031681529695505050505050565b600080826001600160a01b0316637ff36fbe6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f10573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f349190611d57565b9150826001600160a01b031663d7cb416f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f989190611d57565b9050915091565b600080600080846001600160a01b0316631755ff216040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fe3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110079190611d57565b90506000816001600160a01b0316633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa158015611049573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061106d9190611e4c565b50505050509150506000866001600160a01b031663ead892be6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110d99190611cda565b90508060000361113e5760405162461bcd60e51b815260206004820152602a60248201527f6e6f7420616c6c6f772063616c6c696e67207768656e206c697175696469747960448201526904e6674496420697320360b41b606482015260840161040b565b6000805460408051630162dc5360e71b8152905183926001600160a01b03169163b16e29809160048083019260209291908290030181865afa158015611188573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111ac9190611d57565b6001600160a01b03166399fbab88846040518263ffffffff1660e01b81526004016111d991815260200190565b61018060405180830381865afa1580156111f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061121b9190611ef4565b5050505050965096505050505050611232846113b5565b975061123d826113b5565b9650611248816113b5565b9799969850505050505050565b6000836001600160a01b0316856001600160a01b03161115611275579293925b846001600160a01b0316866001600160a01b0316116112a0576112998585856117d5565b9050611310565b836001600160a01b0316866001600160a01b031610156113025760006112c78786866117d5565b905060006112d687898661184a565b9050806001600160801b0316826001600160801b0316106112f757806112f9565b815b92505050611310565b61130d85858461184a565b90505b95945050505050565b600080836001600160a01b0316856001600160a01b0316111561133a579293925b846001600160a01b0316866001600160a01b0316116113655761135e858585611880565b91506113ac565b836001600160a01b0316866001600160a01b0316101561139e5761138a868585611880565b915061139785878561194b565b90506113ac565b6113a985858561194b565b90505b94509492505050565b60008060008360020b126113cc578260020b6113d9565b8260020b6113d990611feb565b90506113e8620d89e719612007565b60020b81111561141e5760405162461bcd60e51b81526020600482015260016024820152601560fa1b604482015260640161040b565b60008160011660000361143557600160801b611447565b6ffffcb933bd6fad37aa2d162d1a5940015b70ffffffffffffffffffffffffffffffffff1690506002821615611486576080611481826ffff97272373d413259a46990580e213a612029565b901c90505b60048216156114b05760806114ab826ffff2e50f5f656932ef12357cf3c7fdcc612029565b901c90505b60088216156114da5760806114d5826fffe5caca7e10e4e61c3624eaa0941cd0612029565b901c90505b60108216156115045760806114ff826fffcb9843d60f6159c9db58835c926644612029565b901c90505b602082161561152e576080611529826fff973b41fa98c081472e6896dfb254c0612029565b901c90505b6040821615611558576080611553826fff2ea16466c96a3843ec78b326b52861612029565b901c90505b608082161561158257608061157d826ffe5dee046a99a2a811c461f1969c3053612029565b901c90505b6101008216156115ad5760806115a8826ffcbe86c7900a88aedcffc83b479aa3a4612029565b901c90505b6102008216156115d85760806115d3826ff987a7253ac413176f2b074cf7815e54612029565b901c90505b6104008216156116035760806115fe826ff3392b0822b70005940c7a398e4b70f3612029565b901c90505b61080082161561162e576080611629826fe7159475a2c29b7443b29c7fa6e889d9612029565b901c90505b611000821615611659576080611654826fd097f3bdfd2022b8845ad8f792aa5825612029565b901c90505b61200082161561168457608061167f826fa9f746462d870fdf8a65dc1f90e061e5612029565b901c90505b6140008216156116af5760806116aa826f70d869a156d2a1b890bb3df62baf32f7612029565b901c90505b6180008216156116da5760806116d5826f31be135f97d08fd981231505542fcfa6612029565b901c90505b62010000821615611706576080611701826f09aa508b5b7a84e1c677de54f3e99bc9612029565b901c90505b6202000082161561173157608061172c826e5d6af8dedb81196699c329225ee604612029565b901c90505b6204000082161561175b576080611756826d2216e584f5fa1ea926041bedfe98612029565b901c90505b6208000082161561178357608061177e826b048a170391f7dc42444e8fa2612029565b901c90505b60008460020b131561179e5761179b81600019612056565b90505b6117ad6401000000008261206a565b156117b95760016117bc565b60005b6117cd9060ff16602083901c61207e565b949350505050565b6000826001600160a01b0316846001600160a01b031611156117f5579192915b6000611818856001600160a01b0316856001600160a01b0316600160601b611991565b905061183f61183a848361182c8989612091565b6001600160a01b0316611991565b611b08565b9150505b9392505050565b6000826001600160a01b0316846001600160a01b0316111561186a579192915b6117cd61183a83600160601b61182c8888612091565b6000826001600160a01b0316846001600160a01b031611156118a0579192915b60006001600160a01b0385166118e2600160601b600160e01b03606086901b166118ca8888612091565b6001600160a01b0316876001600160a01b0316611991565b6118ec9190612056565b905080156118fb579050611843565b6119436119216001600160a01b038716600160601b600160e01b03606087901b16612056565b61192b8787612091565b6001600160a01b0316866001600160a01b0316611991565b915050611843565b6000826001600160a01b0316846001600160a01b0316111561196b579192915b6117cd6001600160801b0383166119828686612091565b6001600160a01b0316600160601b5b60008080600019858709858702925082811083820303915050806000036119ca57600084116119bf57600080fd5b508290049050611843565b8084116119d657600080fd5b60008486880980840393811190920391905060006119f68619600161207e565b958690049593849004936000819003046001019050611a158184612029565b909317926000611a26876003612029565b6002189050611a358188612029565b611a409060026120b8565b611a4a9082612029565b9050611a568188612029565b611a619060026120b8565b611a6b9082612029565b9050611a778188612029565b611a829060026120b8565b611a8c9082612029565b9050611a988188612029565b611aa39060026120b8565b611aad9082612029565b9050611ab98188612029565b611ac49060026120b8565b611ace9082612029565b9050611ada8188612029565b611ae59060026120b8565b611aef9082612029565b9050611afb8186612029565b9998505050505050505050565b806001600160801b0381168114611b1e57600080fd5b919050565b6001600160a01b0381168114611b3857600080fd5b50565b60008060408385031215611b4e57600080fd5b8235611b5981611b23565b946020939093013593505050565b60008060408385031215611b7a57600080fd5b8235611b8581611b23565b91506020830135611b9581611b23565b809150509250929050565b8015158114611b3857600080fd5b60008060008060008060c08789031215611bc757600080fd5b8635611bd281611b23565b95506020870135611be281611ba0565b94506040870135611bf281611b23565b959894975094956060810135955060808101359460a0909101359350915050565b600060208284031215611c2557600080fd5b813561184381611b23565b600080600080600060a08688031215611c4857600080fd5b8535611c5381611b23565b94506020860135611c6381611b23565b94979496505050506040830135926060810135926080909101359150565b600080600060608486031215611c9657600080fd5b8335611ca181611b23565b95602085013595506040909401359392505050565b60008060408385031215611cc957600080fd5b505080516020909101519092909150565b600060208284031215611cec57600080fd5b5051919050565b9915158a526001600160a01b039890981660208a0152604089019690965260608801949094526001600160801b0392909216608087015260a086015260c085015260e08401526101008301526101208201526101400190565b8051611b1e81611b23565b600060208284031215611d6957600080fd5b815161184381611b23565b6000825160005b81811015611d955760208186018101518583015201611d7b565b506000920191825250919050565b600060208284031215611db557600080fd5b815161184381611ba0565b80516001600160801b0381168114611b1e57600080fd5b60008060008060008060c08789031215611df057600080fd5b611df987611dc0565b95506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b8051600281900b8114611b1e57600080fd5b805161ffff81168114611b1e57600080fd5b600080600080600080600060e0888a031215611e6757600080fd5b8751611e7281611b23565b9650611e8060208901611e28565b9550611e8e60408901611e3a565b9450611e9c60608901611e3a565b9350611eaa60808901611e3a565b925060a088015160ff81168114611ec057600080fd5b60c0890151909250611ed181611ba0565b8091505092959891949750929550565b805162ffffff81168114611b1e57600080fd5b6000806000806000806000806000806000806101808d8f031215611f1757600080fd5b8c516bffffffffffffffffffffffff81168114611f3357600080fd5b9b50611f4160208e01611d4c565b9a50611f4f60408e01611d4c565b9950611f5d60608e01611d4c565b9850611f6b60808e01611ee1565b9750611f7960a08e01611e28565b9650611f8760c08e01611e28565b9550611f9560e08e01611dc0565b94506101008d015193506101208d01519250611fb46101408e01611dc0565b9150611fc36101608e01611dc0565b90509295989b509295989b509295989b565b634e487b7160e01b600052601160045260246000fd5b6000600160ff1b820161200057612000611fd5565b5060000390565b60008160020b627fffff19810361202057612020611fd5565b60000392915050565b80820281158282048414176103b1576103b1611fd5565b634e487b7160e01b600052601260045260246000fd5b60008261206557612065612040565b500490565b60008261207957612079612040565b500690565b808201808211156103b1576103b1611fd5565b6001600160a01b038281168282160390808211156120b1576120b1611fd5565b5092915050565b818103818111156103b1576103b1611fd556fea2646970667358221220c7471065f870e7db33d3937d69802abdd6f2547569c3feb4af13919ca5eae6d064736f6c63430008120033000000000000000000000000ac709f816af2ee3a2ac7b70bfa6a8a110c6c7634000000000000000000000000676c0eb0d8d16aeabe1a99db07913b5dffd89f0b

Deployed Bytecode

0x60806040526004361061007b5760003560e01c8063d279c1911161004e578063d279c19114610120578063d85bb20514610140578063e231f7d514610153578063fafc80991461018857600080fd5b806306d47de9146100805780631bf840c1146100a25780635cb7d1f4146100d5578063b35924a11461010d575b600080fd5b34801561008c57600080fd5b506100a061009b366004611b3b565b6101a8565b005b3480156100ae57600080fd5b506100c26100bd366004611b67565b610340565b6040519081526020015b60405180910390f35b3480156100e157600080fd5b506000546100f5906001600160a01b031681565b6040516001600160a01b0390911681526020016100cc565b6100a061011b366004611bae565b6103b7565b34801561012c57600080fd5b506100a061013b366004611c13565b6105d8565b6100a061014e366004611c30565b610745565b34801561015f57600080fd5b5061017361016e366004611c81565b610b68565b604080519283526020830191909152016100cc565b34801561019457600080fd5b506001546100f5906001600160a01b031681565b6040516306d47de960e01b81523360048201526024810182905260009081906001600160a01b038516906306d47de99060440160408051808303816000875af11580156101f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061021d9190611cb6565b91509150836001600160a01b031663ead892be6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561025f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102839190611cda565b6040516303c4f78760e51b81523360048201819052906001600160a01b038716907fceee31e29d568de062f944bd6ff828723e2e4c3590ef604b5370647249800469908790839063789ef0e090602401602060405180830381865afa1580156102f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103149190611cda565b60408051928352602083019190915281018790526060810186905260800160405180910390a450505050565b6040516303c4f78760e51b81526001600160a01b0382811660048301526000919084169063789ef0e090602401602060405180830381865afa15801561038a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103ae9190611cda565b90505b92915050565b8415806103c357508234145b6104145760405162461bcd60e51b815260206004820152601960248201527f6d73672e76616c756520213d205f696e707574416d6f756e740000000000000060448201526064015b60405180910390fd5b848061041e575034155b61045b5760405162461bcd60e51b815260206004820152600e60248201526d06d73672e76616c756520213d20360941b604482015260640161040b565b846104775761046c84333086610bac565b610477848785610cb6565b6000610487878787878787610db6565b6040516303c4f78760e51b81523360048201529091506000906001600160a01b0389169063789ef0e090602401602060405180830381865afa1580156104d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f59190611cda565b9050876001600160a01b031663ead892be6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610535573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105599190611cda565b336001600160a01b0316896001600160a01b03167fd5a9f37d804ba98f2d513a8ebca817086cd1060534f07c44eb012c8a492c051f8a8a8a8789600001518a602001518b604001518c606001518d608001518e60a001516040516105c69a99989796959493929190611cf3565b60405180910390a45050505050505050565b604051637a1cdbcf60e01b81523360048201526000906001600160a01b03831690637a1cdbcf90602401602060405180830381865afa15801561061f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106439190611cda565b60405163d279c19160e01b81523360048201529091506001600160a01b0383169063d279c19190602401600060405180830381600087803b15801561068757600080fd5b505af115801561069b573d6000803e3d6000fd5b50505050816001600160a01b031663ead892be6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107019190611cda565b60405182815233906001600160a01b038516907ffe7c5fc89da23a432c91f264decb100ab9d08ab7b14650c3cdb9b6b4f84a60e99060200160405180910390a45050565b34156107845760405162461bcd60e51b815260206004820152600e60248201526d06d73672e76616c756520213d20360941b604482015260640161040b565b60008054906101000a90046001600160a01b03166001600160a01b031663bb09d9b76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107f99190611d57565b6001600160a01b0316846001600160a01b0316148061089d575060008054906101000a90046001600160a01b03166001600160a01b03166341104a226040518163ffffffff1660e01b8152600401602060405180830381865afa158015610864573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108889190611d57565b6001600160a01b0316846001600160a01b0316145b6108e95760405162461bcd60e51b815260206004820152601e60248201527f696e76616c69642055534443206f7220555344432e6520616464726573730000604482015260640161040b565b6000806108f587610ecf565b91509150816001600160a01b0316866001600160a01b0316148061092a5750806001600160a01b0316866001600160a01b0316145b156109435761093e876000888888886103b7565b610b5f565b61094f86333088610bac565b6001546109679087906001600160a01b031687610cb6565b600154604051633b4cdc4360e01b81526000600482018190526001600160a01b03898116602484015285811660448401526064830189905230608484015290921690633b4cdc439060a4016020604051808303816000875af11580156109d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109f59190611cda565b9050610a02838983610cb6565b6000610a1389600086858a8a610db6565b6040516303c4f78760e51b81523360048201529091506000906001600160a01b038b169063789ef0e090602401602060405180830381865afa158015610a5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a819190611cda565b9050896001600160a01b031663ead892be6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ac1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ae59190611cda565b336001600160a01b03168b6001600160a01b03167fd5a9f37d804ba98f2d513a8ebca817086cd1060534f07c44eb012c8a492c051f60008d8d8789600001518a602001518b604001518c606001518d608001518e60a00151604051610b539a99989796959493929190611cf3565b60405180910390a45050505b50505050505050565b6000806000806000610b7988610f9f565b9250925092506000610b8e8484848b8b611255565b9050610b9c84848484611319565b909a909950975050505050505050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b1790529151600092839290881691610c109190611d74565b6000604051808303816000865af19150503d8060008114610c4d576040519150601f19603f3d011682016040523d82523d6000602084013e610c52565b606091505b5091509150818015610c7c575080511580610c7c575080806020019051810190610c7c9190611da3565b610cae5760405162461bcd60e51b815260206004820152600360248201526229aa2360e91b604482015260640161040b565b505050505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663095ea7b360e01b1790529151600092839290871691610d129190611d74565b6000604051808303816000865af19150503d8060008114610d4f576040519150601f19603f3d011682016040523d82523d6000602084013e610d54565b606091505b5091509150818015610d7e575080511580610d7e575080806020019051810190610d7e9190611da3565b610daf5760405162461bcd60e51b8152602060048201526002602482015261534160f01b604482015260640161040b565b5050505050565b610df86040518060c0016040528060006001600160801b0316815260200160008152602001600081526020016000815260200160008152602001600081525090565b866001600160a01b031663d9933d5a87610e13576000610e15565b855b6040516001600160e01b031960e084901b16815289151560048201523360248201526001600160a01b0389166044820152606481018890526084810187905260a4810186905260c40160c06040518083038185885af1158015610e7c573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610ea19190611dd7565b60a087015260808601526060850152604084015260208301526001600160801b031681529695505050505050565b600080826001600160a01b0316637ff36fbe6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f10573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f349190611d57565b9150826001600160a01b031663d7cb416f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f989190611d57565b9050915091565b600080600080846001600160a01b0316631755ff216040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fe3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110079190611d57565b90506000816001600160a01b0316633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa158015611049573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061106d9190611e4c565b50505050509150506000866001600160a01b031663ead892be6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110d99190611cda565b90508060000361113e5760405162461bcd60e51b815260206004820152602a60248201527f6e6f7420616c6c6f772063616c6c696e67207768656e206c697175696469747960448201526904e6674496420697320360b41b606482015260840161040b565b6000805460408051630162dc5360e71b8152905183926001600160a01b03169163b16e29809160048083019260209291908290030181865afa158015611188573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111ac9190611d57565b6001600160a01b03166399fbab88846040518263ffffffff1660e01b81526004016111d991815260200190565b61018060405180830381865afa1580156111f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061121b9190611ef4565b5050505050965096505050505050611232846113b5565b975061123d826113b5565b9650611248816113b5565b9799969850505050505050565b6000836001600160a01b0316856001600160a01b03161115611275579293925b846001600160a01b0316866001600160a01b0316116112a0576112998585856117d5565b9050611310565b836001600160a01b0316866001600160a01b031610156113025760006112c78786866117d5565b905060006112d687898661184a565b9050806001600160801b0316826001600160801b0316106112f757806112f9565b815b92505050611310565b61130d85858461184a565b90505b95945050505050565b600080836001600160a01b0316856001600160a01b0316111561133a579293925b846001600160a01b0316866001600160a01b0316116113655761135e858585611880565b91506113ac565b836001600160a01b0316866001600160a01b0316101561139e5761138a868585611880565b915061139785878561194b565b90506113ac565b6113a985858561194b565b90505b94509492505050565b60008060008360020b126113cc578260020b6113d9565b8260020b6113d990611feb565b90506113e8620d89e719612007565b60020b81111561141e5760405162461bcd60e51b81526020600482015260016024820152601560fa1b604482015260640161040b565b60008160011660000361143557600160801b611447565b6ffffcb933bd6fad37aa2d162d1a5940015b70ffffffffffffffffffffffffffffffffff1690506002821615611486576080611481826ffff97272373d413259a46990580e213a612029565b901c90505b60048216156114b05760806114ab826ffff2e50f5f656932ef12357cf3c7fdcc612029565b901c90505b60088216156114da5760806114d5826fffe5caca7e10e4e61c3624eaa0941cd0612029565b901c90505b60108216156115045760806114ff826fffcb9843d60f6159c9db58835c926644612029565b901c90505b602082161561152e576080611529826fff973b41fa98c081472e6896dfb254c0612029565b901c90505b6040821615611558576080611553826fff2ea16466c96a3843ec78b326b52861612029565b901c90505b608082161561158257608061157d826ffe5dee046a99a2a811c461f1969c3053612029565b901c90505b6101008216156115ad5760806115a8826ffcbe86c7900a88aedcffc83b479aa3a4612029565b901c90505b6102008216156115d85760806115d3826ff987a7253ac413176f2b074cf7815e54612029565b901c90505b6104008216156116035760806115fe826ff3392b0822b70005940c7a398e4b70f3612029565b901c90505b61080082161561162e576080611629826fe7159475a2c29b7443b29c7fa6e889d9612029565b901c90505b611000821615611659576080611654826fd097f3bdfd2022b8845ad8f792aa5825612029565b901c90505b61200082161561168457608061167f826fa9f746462d870fdf8a65dc1f90e061e5612029565b901c90505b6140008216156116af5760806116aa826f70d869a156d2a1b890bb3df62baf32f7612029565b901c90505b6180008216156116da5760806116d5826f31be135f97d08fd981231505542fcfa6612029565b901c90505b62010000821615611706576080611701826f09aa508b5b7a84e1c677de54f3e99bc9612029565b901c90505b6202000082161561173157608061172c826e5d6af8dedb81196699c329225ee604612029565b901c90505b6204000082161561175b576080611756826d2216e584f5fa1ea926041bedfe98612029565b901c90505b6208000082161561178357608061177e826b048a170391f7dc42444e8fa2612029565b901c90505b60008460020b131561179e5761179b81600019612056565b90505b6117ad6401000000008261206a565b156117b95760016117bc565b60005b6117cd9060ff16602083901c61207e565b949350505050565b6000826001600160a01b0316846001600160a01b031611156117f5579192915b6000611818856001600160a01b0316856001600160a01b0316600160601b611991565b905061183f61183a848361182c8989612091565b6001600160a01b0316611991565b611b08565b9150505b9392505050565b6000826001600160a01b0316846001600160a01b0316111561186a579192915b6117cd61183a83600160601b61182c8888612091565b6000826001600160a01b0316846001600160a01b031611156118a0579192915b60006001600160a01b0385166118e2600160601b600160e01b03606086901b166118ca8888612091565b6001600160a01b0316876001600160a01b0316611991565b6118ec9190612056565b905080156118fb579050611843565b6119436119216001600160a01b038716600160601b600160e01b03606087901b16612056565b61192b8787612091565b6001600160a01b0316866001600160a01b0316611991565b915050611843565b6000826001600160a01b0316846001600160a01b0316111561196b579192915b6117cd6001600160801b0383166119828686612091565b6001600160a01b0316600160601b5b60008080600019858709858702925082811083820303915050806000036119ca57600084116119bf57600080fd5b508290049050611843565b8084116119d657600080fd5b60008486880980840393811190920391905060006119f68619600161207e565b958690049593849004936000819003046001019050611a158184612029565b909317926000611a26876003612029565b6002189050611a358188612029565b611a409060026120b8565b611a4a9082612029565b9050611a568188612029565b611a619060026120b8565b611a6b9082612029565b9050611a778188612029565b611a829060026120b8565b611a8c9082612029565b9050611a988188612029565b611aa39060026120b8565b611aad9082612029565b9050611ab98188612029565b611ac49060026120b8565b611ace9082612029565b9050611ada8188612029565b611ae59060026120b8565b611aef9082612029565b9050611afb8186612029565b9998505050505050505050565b806001600160801b0381168114611b1e57600080fd5b919050565b6001600160a01b0381168114611b3857600080fd5b50565b60008060408385031215611b4e57600080fd5b8235611b5981611b23565b946020939093013593505050565b60008060408385031215611b7a57600080fd5b8235611b8581611b23565b91506020830135611b9581611b23565b809150509250929050565b8015158114611b3857600080fd5b60008060008060008060c08789031215611bc757600080fd5b8635611bd281611b23565b95506020870135611be281611ba0565b94506040870135611bf281611b23565b959894975094956060810135955060808101359460a0909101359350915050565b600060208284031215611c2557600080fd5b813561184381611b23565b600080600080600060a08688031215611c4857600080fd5b8535611c5381611b23565b94506020860135611c6381611b23565b94979496505050506040830135926060810135926080909101359150565b600080600060608486031215611c9657600080fd5b8335611ca181611b23565b95602085013595506040909401359392505050565b60008060408385031215611cc957600080fd5b505080516020909101519092909150565b600060208284031215611cec57600080fd5b5051919050565b9915158a526001600160a01b039890981660208a0152604089019690965260608801949094526001600160801b0392909216608087015260a086015260c085015260e08401526101008301526101208201526101400190565b8051611b1e81611b23565b600060208284031215611d6957600080fd5b815161184381611b23565b6000825160005b81811015611d955760208186018101518583015201611d7b565b506000920191825250919050565b600060208284031215611db557600080fd5b815161184381611ba0565b80516001600160801b0381168114611b1e57600080fd5b60008060008060008060c08789031215611df057600080fd5b611df987611dc0565b95506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b8051600281900b8114611b1e57600080fd5b805161ffff81168114611b1e57600080fd5b600080600080600080600060e0888a031215611e6757600080fd5b8751611e7281611b23565b9650611e8060208901611e28565b9550611e8e60408901611e3a565b9450611e9c60608901611e3a565b9350611eaa60808901611e3a565b925060a088015160ff81168114611ec057600080fd5b60c0890151909250611ed181611ba0565b8091505092959891949750929550565b805162ffffff81168114611b1e57600080fd5b6000806000806000806000806000806000806101808d8f031215611f1757600080fd5b8c516bffffffffffffffffffffffff81168114611f3357600080fd5b9b50611f4160208e01611d4c565b9a50611f4f60408e01611d4c565b9950611f5d60608e01611d4c565b9850611f6b60808e01611ee1565b9750611f7960a08e01611e28565b9650611f8760c08e01611e28565b9550611f9560e08e01611dc0565b94506101008d015193506101208d01519250611fb46101408e01611dc0565b9150611fc36101608e01611dc0565b90509295989b509295989b509295989b565b634e487b7160e01b600052601160045260246000fd5b6000600160ff1b820161200057612000611fd5565b5060000390565b60008160020b627fffff19810361202057612020611fd5565b60000392915050565b80820281158282048414176103b1576103b1611fd5565b634e487b7160e01b600052601260045260246000fd5b60008261206557612065612040565b500490565b60008261207957612079612040565b500690565b808201808211156103b1576103b1611fd5565b6001600160a01b038281168282160390808211156120b1576120b1611fd5565b5092915050565b818103818111156103b1576103b1611fd556fea2646970667358221220c7471065f870e7db33d3937d69802abdd6f2547569c3feb4af13919ca5eae6d064736f6c63430008120033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000ac709f816af2ee3a2ac7b70bfa6a8a110c6c7634000000000000000000000000676c0eb0d8d16aeabe1a99db07913b5dffd89f0b

-----Decoded View---------------
Arg [0] : _constants (address): 0xac709f816aF2ee3a2ac7B70bfa6A8a110C6c7634
Arg [1] : _zap (address): 0x676c0EB0d8d16aeabE1A99db07913B5Dffd89f0B

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000ac709f816af2ee3a2ac7b70bfa6a8a110c6c7634
Arg [1] : 000000000000000000000000676c0eb0d8d16aeabe1a99db07913b5dffd89f0b


Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
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.