ETH Price: $2,703.88 (+2.85%)

Contract

0x56F292Cd75De83D43e7A8D8D5E21677220c3289E
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Exit Farm217497972025-02-01 6:11:5918 days ago1738390319IN
0x56F292Cd...220c3289E
0 ETH0.006428392.5
Exit Farm217497922025-02-01 6:10:5918 days ago1738390259IN
0x56F292Cd...220c3289E
0 ETH0.006991072.5
Exit Farm217434632025-01-31 8:57:4719 days ago1738313867IN
0x56F292Cd...220c3289E
0 ETH0.008081613.33383522
Exit Farm217282252025-01-29 5:53:5921 days ago1738130039IN
0x56F292Cd...220c3289E
0 ETH0.004741431.87340188
Enter Farm217282132025-01-29 5:51:3521 days ago1738129895IN
0x56F292Cd...220c3289E
0 ETH0.007160381.93347877
Exit Farm217177832025-01-27 18:55:1123 days ago1738004111IN
0x56F292Cd...220c3289E
0 ETH0.0292090512.68604318
Enter Farm217177772025-01-27 18:53:5923 days ago1738004039IN
0x56F292Cd...220c3289E
0 ETH0.0468161513.32049095
Exit Farm216932502025-01-24 8:45:2326 days ago1737708323IN
0x56F292Cd...220c3289E
0 ETH0.013209655.20899729
Enter Farm213572532024-12-08 10:43:5973 days ago1733654639IN
0x56F292Cd...220c3289E
0 ETH0.03488748.39056846
Manually Payback...213481042024-12-07 4:02:5974 days ago1733544179IN
0x56F292Cd...220c3289E
0 ETH0.0049121612.44698843
Enter Farm212461422024-11-22 22:05:4788 days ago1732313147IN
0x56F292Cd...220c3289E
0 ETH0.0847131920.5158872
Enter Farm212035992024-11-16 23:38:3594 days ago1731800315IN
0x56F292Cd...220c3289E
0 ETH0.0405212110.42537004
Enter Farm211765732024-11-13 5:07:1198 days ago1731474431IN
0x56F292Cd...220c3289E
0 ETH0.1040212225.6
Enter Farm211554342024-11-10 6:20:23101 days ago1731219623IN
0x56F292Cd...220c3289E
0 ETH0.0623328914.7
Change Min Depos...211517992024-11-09 18:10:23102 days ago1731175823IN
0x56F292Cd...220c3289E
0 ETH0.000280979.3458716
Set White List F...211414172024-11-08 7:26:11103 days ago1731050771IN
0x56F292Cd...220c3289E
0 ETH0.001127037.56255376

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
EthenaApiRoutingUsdc

Compiler Version
v0.8.25+commit.b61c2a91

Optimization Enabled:
Yes with 20 runs

Other Settings:
cancun EvmVersion
File 1 of 31 : EthenaPowerFarmUsdc.sol
// SPDX-License-Identifier: -- WISE --

pragma solidity =0.8.25;

import "./EthenaPowerFarm.sol";

/**
 * @title EthenaApiRoutingUsdc
 * @notice Derived contract for specific assets
 */

contract EthenaApiRoutingUsdc is EthenaPowerFarm {

    address public constant AAVE_NATIVE_USDC_ARBITRUM_ADDRESS = address(
        0x724dc807b04555b71ed48a6896b6F41593b8C637
    );

    address public constant NATIVE_USDC_ARBITRUM_ADDRESS = address(
        0xaf88d065e77c8cC2239327C5EDb3A432268e5831
    );

    address public constant USDC_ETH_MAIN = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;
    address public AAVE_USDC_ADDRESS_ETH_MAIN = 0x98C23E9d8f34FEFb1B7BD6a91B7FF122F4e16F5c;

    constructor(
        address _wiseLendingAddress,
        address _pendleChildTokenAddress,
        address _pendleRouter,
        address _entryAsset,
        address _pendleSy,
        address _underlyingMarket,
        address _routerStatic,
        address _dexAddress,
        uint256 _collateralFactor,
        address _powerFarmNFTs
    )
        EthenaPowerFarm(
            _wiseLendingAddress,
            _pendleChildTokenAddress,
            _pendleRouter,
            _entryAsset,
            _pendleSy,
            _underlyingMarket,
            _routerStatic,
            _dexAddress,
            _collateralFactor,
            _powerFarmNFTs,
            block.chainid == 1
                ? USDC_ETH_MAIN
                : NATIVE_USDC_ARBITRUM_ADDRESS,
            block.chainid == 1
                ? AAVE_USDC_ADDRESS_ETH_MAIN
                : AAVE_NATIVE_USDC_ARBITRUM_ADDRESS
        )
    {}
}

File 2 of 31 : EthenaPowerFarm.sol
// SPDX-License-Identifier: -- WISE --

pragma solidity =0.8.25;

/**
 * @title EthenaPowerFarm
 * @notice Base contract to manage variable assets for other contracts
 */

import "../../GenericPowerManager.sol";

error ApiRoutingCallFailed();
error ApiRoutingDebtRatioTooHigh();
error ApiRoutingTooMuchValueLost();

abstract contract EthenaPowerFarm is GenericPowerManager {

    address USDC_UNI_V3_POOL_ETH_MAIN = 0x4e0924d3a751bE199C426d52fb1f2337fa96f736;

    constructor(
        address _wiseLendingAddress,
        address _pendleChildTokenAddress,
        address _pendleRouter,
        address _entryAsset,
        address _pendleSy,
        address _underlyingMarket,
        address _routerStatic,
        address _dexAddress,
        uint256 _collateralFactor,
        address _powerFarmNFTs,
        address _farmAsset,
        address _poolAssetAave
    )
        GenericPowerManager(
            _wiseLendingAddress,
            _pendleChildTokenAddress,
            _pendleRouter,
            _entryAsset,
            _pendleSy,
            _underlyingMarket,
            _routerStatic,
            _dexAddress,
            _collateralFactor,
            _powerFarmNFTs
        )
    {
        FARM_ASSET = _farmAsset;
        POOL_ASSET_AAVE = _poolAssetAave;

        _doApprovals(
            _wiseLendingAddress
        );

        collateralFactorRole = msg.sender;

        if (block.chainid == 1) {
            UNISWAP_V3_POOL = IUniswapV3PoolPowerFarm(
                USDC_UNI_V3_POOL_ETH_MAIN
            );
        }
    }

    event WhiteListedExternalContract(
        address indexed _contract,
        bool _isWhiteListed
    );

    function setWhiteListForContracts(
        address[] memory _whiteList,
        bool[] memory _isWhiteListed
    )
        external
        onlyMaster
    {
        for (uint256 i = 0; i < _whiteList.length; i++) {
            _setMapping(
                whiteListedExternalContracts,
                _whiteList[i],
                _isWhiteListed[i]
            );

            emit WhiteListedExternalContract(
                _whiteList[i],
                _isWhiteListed[i]
            );
        }
    }

    function changeUniV3Pool(
        address _newUniV3Pool
    )
        external
        override
        onlyMaster
    {
        UNISWAP_V3_POOL = IUniswapV3PoolPowerFarm(
            _newUniV3Pool
        );
    }

    function _setMapping(
        mapping(address => bool) storage _mapping,
        address _key,
        bool _state
    )
        private
    {
        _mapping[_key] = _state;
    }

    function _doApprovals(
        address _wiseLendingAddress
    )
        internal
        virtual
        override
    {
        _safeApprove(
            POOL_ASSET_AAVE,
            _wiseLendingAddress,
            MAX_AMOUNT
        );

        _safeApprove(
            FARM_ASSET,
            PENDLE_LIMIT_ROUTER_ADDRESS,
            MAX_AMOUNT
        );

        _safeApprove(
            address(PENDLE_MARKET),
            PENDLE_LIMIT_ROUTER_ADDRESS,
            MAX_AMOUNT
        );

        _safeApprove(
            address(PENDLE_MARKET),
            address(PENDLE_ROUTER),
            MAX_AMOUNT
        );

        _safeApprove(
            FARM_ASSET,
            _wiseLendingAddress,
            MAX_AMOUNT
        );

        _safeApprove(
            PENDLE_CHILD,
            _wiseLendingAddress,
            MAX_AMOUNT
        );

        _safeApprove(
            address(PENDLE_MARKET),
            PENDLE_CHILD,
            MAX_AMOUNT
        );

        _safeApprove(
            FARM_ASSET,
            address(AAVE_HUB),
            MAX_AMOUNT
        );

        _safeApprove(
            FARM_ASSET,
            address(PENDLE_ROUTER),
            MAX_AMOUNT
        );
    }

    function _logicOpenPosition(
        bytes memory _callData,
        bool _isAave,
        uint256 _nftId,
        uint256 _depositAmount,
        uint256 _totalDebtBalancer,
        uint256 _allowedSpread
    )
        internal
        virtual
        override
    {
        uint256 ethValueBefore = _getTokensInETH(
            FARM_ASSET,
            _depositAmount
        );

        uint256 netLpOut = _routeWithCallData({
            _callData: _callData,
            _addLiquidity: true
        });

        (
            uint256 receivedShares,
        ) = IPendleChild(PENDLE_CHILD).depositExactAmount(
            netLpOut
        );

        uint256 ethValueAfter = _getTokensInETH(
            PENDLE_CHILD,
            receivedShares
        )
            * _allowedSpread
            / PRECISION_FACTOR_E18;

        if (ethValueAfter < ethValueBefore) {
            revert ApiRoutingTooMuchValueLost();
        }

        WISE_LENDING.depositExactAmount(
            _nftId,
            PENDLE_CHILD,
            receivedShares
        );

        _borrowExactAmount(
            _isAave,
            _nftId,
            _totalDebtBalancer
        );

        if (_checkDebtRatio(_nftId) == false) {
            revert ApiRoutingDebtRatioTooHigh();
        }

        if (block.chainid == 1) {
            _safeTransfer(
                FARM_ASSET,
                address(UNISWAP_V3_POOL),
                _totalDebtBalancer
            );

            return;
        }

        _safeTransfer(
            FARM_ASSET,
            BALANCER_ADDRESS,
            _totalDebtBalancer
        );
    }

    function _logicClosePosition(
        bytes memory _callData,
        uint256 _nftId,
        uint256 _borrowShares,
        uint256 _lendingShares,
        uint256 _totalDebtBalancer,
        uint256 _allowedSpread,
        address _caller,
        bool,
        bool _isAave
    )
        internal
        virtual
        override
    {
        _paybackExactShares(
            _isAave,
            _nftId,
            _borrowShares
        );

        uint256 ethValueBefore = _getTokensInETH(
            PENDLE_CHILD,
            IPendleChild(PENDLE_CHILD).previewAmountWithdrawShares(
                _getCashoutAmount(
                    PENDLE_CHILD,
                    _getPositionLendingShares(_nftId)
                ),
                IPendleChild(PENDLE_CHILD).underlyingLpAssetsCurrent()
            )
        );

        _withdrawPendleLPs(
            _nftId,
            _lendingShares
        );

        uint256 netTokenOut = _routeWithCallData({
            _callData: _callData,
            _addLiquidity: false
        });

        uint256 ethValueAfter = _getTokensInETH(
            FARM_ASSET,
            netTokenOut
        )
            * _allowedSpread
            / PRECISION_FACTOR_E18;

        if (ethValueAfter < ethValueBefore) {
            revert ApiRoutingTooMuchValueLost();
        }

        _closingRouteToken(
            netTokenOut,
            _totalDebtBalancer,
            _caller
        );
    }

    function _routeWithCallData(
        bytes memory _callData,
        bool _addLiquidity
    )
        private
        returns (uint256)
    {
        _verifyCallData({
            _callData: _callData,
            _addLiquidity: _addLiquidity
        });

        (
            bool success,
            bytes memory returnData
        ) = _callPendleRouter(
            _callData
        );

        if (success == false) {
            revert ApiRoutingCallFailed();
        }

        (
            uint256 netTokenOut,
            ,
        ) = abi.decode(
            returnData,
            (
                uint256,
                uint256,
                uint256
            )
        );

        return netTokenOut;
    }
}

File 3 of 31 : GenericPowerManager.sol
// SPDX-License-Identifier: -- WISE --

pragma solidity =0.8.25;

/**
 * @author René Hochmuth
 * @author Christoph Krpoun
 * @author Vitally Marinchenko
 */

import "../OwnableMaster.sol";

import "./GenericPowerFarm.sol";
import "./PowerFarmNFTs/MinterReserver.sol";

contract GenericPowerManager is
    OwnableMaster,
    GenericPowerFarm,
    MinterReserver
{
    receive()
        external
        payable
        virtual
    {
        emit ETHReceived(
            msg.value,
            msg.sender
        );

        if (msg.sender == WETH_ADDRESS) {
            return;
        }

        if (sendingProgress == true) {
            revert GenericSendingOnGoing();
        }

        _sendValue(
            master,
            msg.value
        );
    }

    constructor(
        address _wiseLendingAddress,
        address _pendleChildTokenAddress,
        address _pendleRouter,
        address _entryAsset,
        address _pendleSy,
        address _underlyingMarket,
        address _routerStatic,
        address _dexAddress,
        uint256 _collateralFactor,
        address _powerFarmNFTs
    )
        OwnableMaster(msg.sender)
        MinterReserver(_powerFarmNFTs)
        GenericDeclarations(
            _wiseLendingAddress,
            _pendleChildTokenAddress,
            _pendleRouter,
            _entryAsset,
            _pendleSy,
            _underlyingMarket,
            _routerStatic,
            _dexAddress,
            _collateralFactor
        )
    {}

    function setSpecialDepegCase(
        bool _state
    )
        external
        virtual
        onlyMaster
    {
        specialDepegCase = _state;
    }

    function revokeCollateralFactorRole()
        public
        virtual
        onlyCollateralFactorRole
    {
        collateralFactorRole = ZERO_ADDRESS;
    }

    function setCollateralFactor(
        uint256 _newCollateralFactor
    )
        external
        override
        onlyCollateralFactorRole()
    {
        collateralFactor = _newCollateralFactor;
    }

    function changeMinDeposit(
        uint256 _newMinDeposit
    )
        external
        virtual
        onlyMaster
    {
        minDepositEthAmount = _newMinDeposit;

        emit MinDepositChange(
            _newMinDeposit,
            block.timestamp
        );
    }

    /**
     * @dev External function deactivating the power farm by
     * disableing the openPosition function. Allowing user
     * to manualy payback and withdraw.
     */
    function shutDownFarm(
        bool _state
    )
        external
        virtual
        onlyMaster
    {
        isShutdown = _state;

        emit FarmStatus(
            _state,
            block.timestamp
        );
    }

    function enterFarm(
        bytes memory _callData,
        bool _isAave,
        uint256 _amount,
        uint256 _leverage,
        uint256 _allowedSpread
    )
        public
        virtual
        routingOngoingCheck
        isActive
        updatePools
        returns (uint256)
    {
        _safeTransferFrom(
            FARM_ASSET,
            msg.sender,
            address(this),
            _amount
        );

        return _handleEnterFarm(
            _callData,
            _isAave,
            _getWiseLendingNFT(),
            _amount,
            _leverage,
            _allowedSpread
        );
    }

    function _handleEnterFarm(
        bytes memory _callData,
        bool _isAave,
        uint256 _wiseLendingNFT,
        uint256 _amount,
        uint256 _leverage,
        uint256 _allowedSpread
    )
        private
        returns (uint256)
    {
        _openPosition(
            _callData,
            _isAave,
            _wiseLendingNFT,
            _amount,
            _leverage,
            _allowedSpread
        );

        return _handleEntryFarmStorage(
            _wiseLendingNFT,
            _isAave,
            _leverage,
            _amount
        );
    }

    function _handleEntryFarmStorage(
        uint256 _wiseLendingNFT,
        bool _isAave,
        uint256 _leverage,
        uint256 _amount
    )
        internal
        returns (uint256)
    {
        uint256 keyId = _reserveKey(
            msg.sender,
            _wiseLendingNFT
        );

        isAave[_wiseLendingNFT] = _isAave;

        _storeData(
            keyId,
            _wiseLendingNFT,
            _leverage,
            _amount,
            getTokenAmountEquivalentInFarmAsset(_wiseLendingNFT),
            block.timestamp
        );

        return keyId;
    }

    function _storeData(
        uint256 _keyId,
        uint256 _wiseLendingNFT,
        uint256 _leverage,
        uint256 _amount,
        uint256 _amountAfterMintFee,
        uint256 _timestamp
    )
        internal
        virtual
    {
        FarmData memory FarmData = FarmData(
            _wiseLendingNFT,
            _leverage,
            _amount,
            _amountAfterMintFee,
            _timestamp
        );

        farmData[_keyId] = FarmData;

        emit FarmEntry(
            _keyId,
            _wiseLendingNFT,
            _leverage,
            _amount,
            _amountAfterMintFee,
            _timestamp
        );
    }

    function enterFarmETH(
        bytes memory _callData,
        bool _isAave,
        uint256 _leverage,
        uint256 _allowedSpread
    )
        external
        virtual
        payable
        routingOngoingCheck
        isActive
        updatePools
        returns (uint256)
    {
        _wrapETH(
            msg.value
        );

        return _handleEnterFarm(
            _callData,
            _isAave,
            _getWiseLendingNFT(),
            msg.value,
            _leverage,
            _allowedSpread
        );
    }

    function _getWiseLendingNFT()
        internal
        virtual
        returns (uint256)
    {
        if (availableNFTCount == 0) {

            uint256 nftId = POSITION_NFT.mintPosition();

            _registrationFarm(
                nftId
            );

            POSITION_NFT.approve(
                AAVE_HUB_ADDRESS,
                nftId
            );

            return nftId;
        }

        return availableNFTs[
            availableNFTCount--
        ];
    }

    function exitFarm(
        bytes memory _callData,
        uint256 _keyId,
        uint256 _allowedSpread,
        bool _ethBack
    )
        external
        virtual
        routingOngoingCheck
        updatePools
        onlyKeyOwner(_keyId)
    {
        uint256 wiseLendingNFT = farmingKeys[
            _keyId
        ];

        delete farmingKeys[
            _keyId
        ];

        if (reservedKeys[msg.sender] == _keyId) {
            reservedKeys[msg.sender] = 0;
        } else {
            FARMS_NFTS.burnKey(
                _keyId
            );
        }

        availableNFTs[
            ++availableNFTCount
        ] = wiseLendingNFT;

        _closingPosition(
            _callData,
            isAave[wiseLendingNFT],
            wiseLendingNFT,
            _allowedSpread,
            _ethBack
        );

        emit FarmExit(
            _keyId,
            wiseLendingNFT,
            _allowedSpread,
            block.timestamp
        );
    }

    function manuallyPaybackShares(
        uint256 _keyId,
        uint256 _paybackShares
    )
        external
        virtual
        routingOngoingCheck
        updatePools
    {
        _manuallyPaybackShares(
            farmingKeys[_keyId],
            _paybackShares
        );

        emit ManualPaybackShares(
            _keyId,
            farmingKeys[_keyId],
            _paybackShares,
            block.timestamp
        );
    }

    function changePendleRouter(
        address _newPendleRouter,
        address _newLimitRouter
    )
        external
        virtual
        onlyMaster
    {
        PENDLE_ROUTER = IPendleRouter(
            _newPendleRouter
        );

        PENDLE_LIMIT_ROUTER_ADDRESS = _newLimitRouter;

        _doApprovals(
            address(WISE_LENDING)
        );
    }

    function manuallyWithdrawShares(
        uint256 _keyId,
        uint256 _withdrawShares
    )
        external
        virtual
        routingOngoingCheck
        updatePools
        onlyKeyOwner(_keyId)
    {
        uint256 wiseLendingNFT = farmingKeys[
            _keyId
        ];

        _manuallyWithdrawShares(
            wiseLendingNFT,
            _withdrawShares
        );

        if (_checkDebtRatio(wiseLendingNFT) == false) {
            revert GenericDebtRatioTooHigh();
        }

        emit ManualWithdrawShares(
            _keyId,
            wiseLendingNFT,
            _withdrawShares,
            block.timestamp
        );
    }
}

File 4 of 31 : OwnableMaster.sol
// SPDX-License-Identifier: -- WISE --

pragma solidity =0.8.25;

error NoValue();
error NotMaster();
error NotProposed();

contract OwnableMaster {

    address public master;
    address public proposedMaster;

    address internal constant ZERO_ADDRESS = address(0x0);

    modifier onlyProposed() {
        _onlyProposed();
        _;
    }

    function _onlyMaster()
        private
        view
    {
        if (msg.sender == master) {
            return;
        }

        revert NotMaster();
    }

    modifier onlyMaster() {
        _onlyMaster();
        _;
    }

    function _onlyProposed()
        private
        view
    {
        if (msg.sender == proposedMaster) {
            return;
        }

        revert NotProposed();
    }

    event MasterProposed(
        address indexed proposer,
        address indexed proposedMaster
    );

    event RenouncedOwnership(
        address indexed previousMaster
    );

    constructor(
        address _master
    ) {
        if (_master == ZERO_ADDRESS) {
            revert NoValue();
        }
        master = _master;
    }

    /**
     * @dev Allows to propose next master.
     * Must be claimed by proposer.
     */
    function proposeOwner(
        address _proposedOwner
    )
        external
        onlyMaster
    {
        if (_proposedOwner == ZERO_ADDRESS) {
            revert NoValue();
        }

        proposedMaster = _proposedOwner;

        emit MasterProposed(
            msg.sender,
            _proposedOwner
        );
    }

    /**
     * @dev Allows to claim master role.
     * Must be called by proposer.
     */
    function claimOwnership()
        external
        onlyProposed
    {
        master = msg.sender;
    }

    /**
     * @dev Removes master role.
     * No ability to be in control.
     */
    function renounceOwnership()
        external
        onlyMaster
    {
        master = ZERO_ADDRESS;
        proposedMaster = ZERO_ADDRESS;

        emit RenouncedOwnership(
            msg.sender
        );
    }
}

File 5 of 31 : GenericPowerFarm.sol
// SPDX-License-Identifier: -- WISE --

pragma solidity =0.8.25;

import "./GenericLeverageLogic.sol";

abstract contract GenericPowerFarm is GenericLeverageLogic {

    /**
     * @dev External view function approximating the
     * new resulting net APY for a position setup.
     *
     * Note: Not 100% accurate because no syncPool is performed.
     */
    function getApproxNetAPY(
        uint256 _initialAmount,
        uint256 _leverage,
        uint256 _pendleChildApy,
        bool _isAave
    )
        external
        virtual
        view
        returns (
            uint256,
            bool
        )
    {
        return _getApproxNetAPY(
            _initialAmount,
            _leverage,
            _pendleChildApy,
            _isAave
        );
    }

    function getTokenAmountEquivalentInFarmAsset(
        uint256 _nftId
    )
        public
        virtual
        view
        returns (uint256)
    {
        uint256 collateralValueInEth = _getTokensInETH(
            PENDLE_CHILD,
            _getPostionCollateralTokenAmount(
                _nftId
            )
        );

        uint256 borrowValueInEth = getPositionBorrowETH(
            _nftId
        );

        if (collateralValueInEth < borrowValueInEth) {
            revert BadDebt(borrowValueInEth - collateralValueInEth);
        }

        return _getEthInTokens(
            FARM_ASSET,
            collateralValueInEth - borrowValueInEth
        );
    }

    /**
     * @dev External view function approximating the
     * new borrow amount for the pool when {_borrowAmount}
     * is borrowed.
     *
     * Note: Not 100% accurate because no syncPool is performed.
     */
    function getNewBorrowRate(
        uint256 _borrowAmount,
        bool _isAave
    )
        external
        virtual
        view
        returns (uint256)
    {
        return _getNewBorrowRate(
            _borrowAmount,
            _isAave
        );
    }

    /**
     * @dev View functions returning the current
     * debt ratio of the postion with {_nftId}
     */
    function getLiveDebtRatio(
        uint256 _nftId
    )
        external
        virtual
        view
        returns (uint256)
    {
        uint256 borrowShares = isAave[_nftId]
            ? _getPositionBorrowSharesAave(
                _nftId
            )
            : _getPositionBorrowShares(
                _nftId
            );

        if (borrowShares == 0) {
            return 0;
        }

        uint256 totalCollateral = getTotalWeightedCollateralETH(
            _nftId
        );

        if (totalCollateral == 0) {
            return 0;
        }

        return getPositionBorrowETH(_nftId)
            * PRECISION_FACTOR_E18
            / totalCollateral;
    }

    function setCollateralFactor(
        uint256 _newCollateralFactor
    )
        external
        virtual
    {}

    /**
     * @dev Liquidation function for open power farm
     * postions which have a debtratio greater than 100%.
     */
    function liquidatePartiallyFromToken(
        uint256 _nftId,
        uint256 _nftIdLiquidator,
        uint256 _shareAmountToPay
    )
        external
        virtual
        routingOngoingCheck
        updatePools
        returns (
            uint256 paybackAmount,
            uint256 receivingAmount
        )
    {
        return _coreLiquidation(
            _nftId,
            _nftIdLiquidator,
            _shareAmountToPay
        );
    }

    /**
     * @dev Manually payback function for users. Takes
     * {_paybackShares} which can be converted
     * into token with {paybackAmount()} or vice verse
     * with {calculateBorrowShares()} from wise lending
     * contract.
     */
    function _manuallyPaybackShares(
        uint256 _nftId,
        uint256 _paybackShares
    )
        internal
        virtual
    {
        address poolAddress = FARM_ASSET;

        if (isAave[_nftId] == true) {
            poolAddress = POOL_ASSET_AAVE;
        }

        uint256 paybackAmount = WISE_LENDING.paybackAmount(
            poolAddress,
            _paybackShares
        );

        _safeTransferFrom(
            poolAddress,
            msg.sender,
            address(this),
            paybackAmount
        );

        WISE_LENDING.paybackExactShares(
            _nftId,
            poolAddress,
            _paybackShares
        );
    }

    /**
     * @dev Manually withdraw function for users. Takes
     * {_withdrawShares} which can be converted
     * into token with {cashoutAmount()} or vice verse
     * with {calculateLendingShares()} from wise lending
     * contract.
     */
    function _manuallyWithdrawShares(
        uint256 _nftId,
        uint256 _withdrawShares
    )
        internal
        virtual
    {
        uint256 withdrawAmount = _getCashoutAmount(
            PENDLE_CHILD,
            _withdrawShares
        );

        withdrawAmount = _withdrawExactShares(
            _nftId,
            PENDLE_CHILD,
            _withdrawShares
        );

        _safeTransfer(
            PENDLE_CHILD,
            msg.sender,
            withdrawAmount
        );
    }

    /**
     * @dev Internal function combining the core
     * logic for {openPosition()}.
     */
    function _openPosition(
        bytes memory _callData,
        bool _isAave,
        uint256 _nftId,
        uint256 _initialAmount,
        uint256 _leverage,
        uint256 _allowedSpread
    )
        internal
        virtual
    {
        if (_leverage > MAX_LEVERAGE) {
            revert GenericLevergeTooHigh();
        }

        uint256 leveragedAmount = getLeverageAmount(
            _initialAmount,
            _leverage
        );

        if (_notBelowMinDepositAmount(leveragedAmount) == false) {
            revert GenericAmountTooSmall();
        }

        _executeBalancerFlashLoan({
            _callData: _callData,
            _nftId: _nftId,
            _flashAmount: leveragedAmount - _initialAmount,
            _initialAmount: _initialAmount,
            _lendingShares: 0,
            _borrowShares: 0,
            _allowedSpread: _allowedSpread,
            _ethBack: ethBack,
            _isAave: _isAave
        });
    }

    /**
     * @dev Internal function combining the core
     * logic for {closingPosition()}.
     *
     * Note: {_allowedSpread} passed through UI by asking user
     * the percentage of acceptable value loss by closing position.
     * Units are in ether where 100% = 1 ether -> 0% loss acceptable
     * 1.01 ether -> 1% loss acceptable and so on.
     */
    function _closingPosition(
        bytes memory _callData,
        bool _isAave,
        uint256 _nftId,
        uint256 _allowedSpread,
        bool _ethBack
    )
        internal
        virtual
    {
        uint256 borrowShares = _isAave == false
            ? _getPositionBorrowShares(
                _nftId
            )
            : _getPositionBorrowSharesAave(
                _nftId
            );

        uint256 borrowTokenAmount = _isAave == false
            ? _getPositionBorrowTokenAmount(
                _nftId
            )
            : _getPositionBorrowTokenAmountAave(
                _nftId
            );

        _executeBalancerFlashLoan({
            _callData: _callData,
            _nftId: _nftId,
            _flashAmount: borrowTokenAmount,
            _initialAmount: 0,
            _lendingShares: _getPositionLendingShares(
                _nftId
            ),
            _borrowShares: borrowShares,
            _allowedSpread: _allowedSpread,
            _ethBack: _ethBack,
            _isAave: _isAave
        });
    }

    function _registrationFarm(
        uint256 _nftId
    )
        internal
        virtual
    {
        WISE_LENDING.setRegistrationIsolationPool(
            _nftId,
            true
        );

        emit RegistrationFarm(
            _nftId,
            block.timestamp
        );
    }
}

File 6 of 31 : MinterReserver.sol
// SPDX-License-Identifier: -- WISE --

pragma solidity =0.8.25;

import "../../InterfaceHub/IPowerFarmsNFTs.sol";

error InvalidKey();
error AlreadyReserved();

contract MinterReserver {

    IPowerFarmsNFTs immutable FARMS_NFTS;

    // Tracks increment of keys
    uint256 public totalMinted;

    // Tracks reserved counter
    uint256 public totalReserved;

    // Tracks amount of reusable NFTs
    uint256 public availableNFTCount;

    // Maps access to wiseLendingNFT through farmNFT
    mapping(uint256 => uint256) public farmingKeys;

    // Tracks reserved NFTs mapped to address
    mapping(address => uint256) public reservedKeys;

    // Tracks reusable wiseLendingNFTs after burn
    mapping(uint256 => uint256) public availableNFTs;

    modifier onlyKeyOwner(
        uint256 _keyId
    ) {
        _onlyKeyOwner(
            _keyId
        );
        _;
    }

    function _onlyKeyOwner(
        uint256 _keyId
    )
        private
        view
    {
        require(
            isOwner(
                _keyId,
                msg.sender
            ) == true
        );
    }

    constructor(
        address _powerFarmNFTs
    ) {
        FARMS_NFTS = IPowerFarmsNFTs(
            _powerFarmNFTs
        );
    }

    function _incrementReserved()
        internal
        returns (uint256)
    {
        return ++totalReserved;
    }

    function _getNextReserveKey()
        internal
        returns (uint256)
    {
        return totalMinted + _incrementReserved();
    }

    function _reserveKey(
        address _userAddress,
        uint256 _wiseLendingNFT
    )
        internal
        returns (uint256)
    {
        if (reservedKeys[_userAddress] > 0) {
            revert AlreadyReserved();
        }

        uint256 keyId = _getNextReserveKey();

        reservedKeys[_userAddress] = keyId;
        farmingKeys[keyId] = _wiseLendingNFT;

        return keyId;
    }

    function isOwner(
        uint256 _keyId,
        address _owner
    )
        public
        view
        returns (bool)
    {
        if (reservedKeys[_owner] == _keyId) {
            return true;
        }

        if (FARMS_NFTS.ownerOf(_keyId) == _owner) {
            return true;
        }

        return false;
    }

    function _mintKeyForUser(
        uint256 _keyId,
        address _userAddress
    )
        internal
        returns (uint256)
    {
        if (_keyId == 0) {
            revert InvalidKey();
        }

        delete reservedKeys[
            _userAddress
        ];

        FARMS_NFTS.mintKey(
            _userAddress,
            _keyId
        );

        totalMinted++;
        totalReserved--;

        return _keyId;
    }

    function mintReserved()
        external
        returns (uint256)
    {
        return _mintKeyForUser(
            reservedKeys[
                msg.sender
            ],
            msg.sender
        );
    }

    event ERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes _data
    );

    function onERC721Received(
        address _operator,
        address _from,
        uint256 _tokenId,
        bytes calldata _data
    )
        external
        returns (bytes4)
    {
        emit ERC721Received(
            _operator,
            _from,
            _tokenId,
            _data
        );

        return this.onERC721Received.selector;
    }
}

File 7 of 31 : GenericLeverageLogic.sol
// SPDX-License-Identifier: -- WISE --

pragma solidity =0.8.25;

import "./GenericMathLogic.sol";

abstract contract GenericLeverageLogic is
    GenericMathLogic,
    IFlashLoanRecipient
{
    /**
     * @dev Wrapper function preparing balancer flashloan and
     * loading data to pass into receiver.
     */
    function _executeBalancerFlashLoan(
        uint256 _nftId,
        uint256 _flashAmount,
        uint256 _initialAmount,
        uint256 _lendingShares,
        uint256 _borrowShares,
        uint256 _allowedSpread,
        bool _ethBack,
        bool _isAave,
        bytes memory _callData
    )
        internal
        virtual
    {
        IERC20[] memory tokens = new IERC20[](1);
        uint256[] memory amount = new uint256[](1);

        tokens[0] = IERC20(FARM_ASSET);
        amount[0] = _flashAmount;

        allowEnter = true;

        if (UNISWAP_V2_POOL != IUniswapV2Pool(address(0))) {
            UNISWAP_V2_POOL.swap(
                0,
                _flashAmount,
                address(this),
                abi.encode(
                    _nftId,
                    _initialAmount,
                    _lendingShares,
                    _borrowShares,
                    _allowedSpread,
                    msg.sender,
                    _ethBack,
                    _isAave,
                    _callData
                )
            );

            return;
        }

        if (UNISWAP_V3_POOL != IUniswapV3PoolPowerFarm(address(0))) {
            ongoingFlashAmountV3 = _flashAmount;

            UNISWAP_V3_POOL.flash(
                address(this),
                UNISWAP_V3_POOL.token0() == FARM_ASSET
                    ? _flashAmount
                    : 0,
                UNISWAP_V3_POOL.token1() == FARM_ASSET
                    ? _flashAmount
                    : 0,
                abi.encode(
                    _nftId,
                    _initialAmount,
                    _lendingShares,
                    _borrowShares,
                    _allowedSpread,
                    msg.sender,
                    _ethBack,
                    _isAave,
                    _callData
                )
            );

            return;
        }

        BALANCER_VAULT.flashLoan(
            this,
            tokens,
            amount,
            abi.encode(
                _nftId,
                _initialAmount,
                _lendingShares,
                _borrowShares,
                _allowedSpread,
                msg.sender,
                _ethBack,
                _isAave,
                _callData
            )
        );
    }

    function uniswapV3FlashCallback(
        uint256 _fee0,
        uint256 _fee1,
        bytes calldata _data
    )
        external
    {
        if (msg.sender != address(UNISWAP_V3_POOL)) {
            revert GenericNotV3Pair(
                msg.sender,
                address(UNISWAP_V3_POOL)
            );
        }

        if (allowEnter == false) {
            revert GenericAccessDenied();
        }

        IERC20[] memory tokens = new IERC20[](1);
        tokens[0] = IERC20(FARM_ASSET);

        uint256[] memory amounts = new uint256[](1);
        amounts[0] = ongoingFlashAmountV3;

        uint256[] memory feeAmounts = new uint256[](1);
        feeAmounts[0] = _fee0 == 0
            ? _fee1
            : _fee0;

        this.receiveFlashLoan(
            tokens,
            amounts,
            feeAmounts,
            _data
        );
    }

    function _validateEntryConditions(
        uint256 _tokenLength,
        address _sender
    )
        private
    {
        if (allowEnter == false) {
            revert GenericAccessDenied();
        }

        allowEnter = false;

        if (_tokenLength == 0) {
            revert GenericInvalidParam();
        }

        if (_sender != BALANCER_ADDRESS ) {
            if (_sender != address(this)) {
                revert GenericNotBalancerVaultOrSelf();
            }
        }
    }

    /**
     * @dev Receive function from balancer flashloan. Body
     * is called from balancer at the end of their {flashLoan()}
     * logic. Overwritten with opening flows.
     */
    function receiveFlashLoan(
        IERC20[] memory _flashloanToken,
        uint256[] memory _flashloanAmounts,
        uint256[] memory _feeAmounts,
        bytes memory _userData
    )
        external
        virtual
    {
        _validateEntryConditions(
            _flashloanToken.length,
            msg.sender
        );

        _processLoan(
            _userData,
            _flashloanAmounts[0],
            _flashloanAmounts[0] + _feeAmounts[0]
        );
    }

    function uniswapV2Call(
        address sender,
        uint256 amount0,
        uint256 amount1,
        bytes calldata data
    )
        external
    {
        address token0 = IUniswapV2Pool(msg.sender).token0();
        address token1 = IUniswapV2Pool(msg.sender).token1();

        address pair = UNISWAP_FACTORY.getPair(
            token0,
            token1
        );

        if (msg.sender != address(UNISWAP_V2_POOL)) {
            revert GenericNotV2Pair(
                msg.sender,
                pair
            );
        }

        if (sender != address(this)) {
            revert GenericNotSender();
        }

        IERC20[] memory tokens = new IERC20[](1);
        tokens[0] = IERC20(
            FARM_ASSET
        );

        uint256[] memory amounts = new uint256[](1);
        amounts[0] = amount0 == 0
            ? amount1
            : amount0;

        uint256[] memory feeAmounts = new uint256[](1);
        feeAmounts[0] = _calculateFlashLoanFee(
            amounts[0]
        );

        this.receiveFlashLoan(
            tokens,
            amounts,
            feeAmounts,
            data
        );
    }

    function _calculateFlashLoanFee(
        uint256 amountWithdrawn
    )
        public
        pure
        returns (uint256)
    {
        return (
            amountWithdrawn
                * 1000
                / 997
            ) - amountWithdrawn
                + 1;
    }

    function _processLoan(
        bytes memory _userData,
        uint256 _flashloanAmount,
        uint256 _totalDebtBalancer
    )
        private
    {
        (
            uint256 nftId,
            uint256 initialAmount,
            uint256 lendingShares,
            uint256 borrowShares,
            uint256 allowedSpread,
            address caller,
            bool ethBack,
            bool isAave,
            bytes memory callData
        ) = abi.decode(
            _userData,
            (
                uint256,
                uint256,
                uint256,
                uint256,
                uint256,
                address,
                bool,
                bool,
                bytes
            )
        );

        if (initialAmount > 0) {
            _logicOpenPosition(
                callData,
                isAave,
                nftId,
                _flashloanAmount + initialAmount,
                _totalDebtBalancer,
                allowedSpread
            );

            return;
        }

        _logicClosePosition(
            callData,
            nftId,
            borrowShares,
            lendingShares,
            _totalDebtBalancer,
            allowedSpread,
            caller,
            ethBack,
            isAave
        );
    }

    function _logicClosePosition(
        bytes memory _callData,
        uint256 _nftId,
        uint256 _borrowShares,
        uint256 _lendingShares,
        uint256 _totalDebtBalancer,
        uint256 _allowedSpread,
        address _caller,
        bool _ethBack,
        bool _isAave
    )
        internal
        virtual
    {}

    function _getEthBack(
        uint256 _swapAmount,
        uint256 _minOutAmount
    )
        internal
        virtual
        returns (uint256)
    {
        uint256 wethAmount = _getTokensUniV3(
            _swapAmount,
            _minOutAmount,
            ENTRY_ASSET,
            FARM_ASSET
        );

        _unwrapETH(
            wethAmount
        );

        return wethAmount;
    }

    function _getTokensUniV3(
        uint256 _amountIn,
        uint256 _minOutAmount,
        address _tokenIn,
        address _tokenOut
    )
        internal
        virtual
        returns (uint256)
    {
        return UNISWAP_V3_ROUTER.exactInputSingle(
            IUniswapV3.ExactInputSingleParams(
                {
                    tokenIn: _tokenIn,
                    tokenOut: _tokenOut,
                    fee: UNISWAP_V3_FEE,
                    recipient: address(this),
                    deadline: block.timestamp,
                    amountIn: _amountIn,
                    amountOutMinimum: _minOutAmount,
                    sqrtPriceLimitX96: 0
                }
            )
        );
    }

    function _swapStETHintoETH(
        uint256 _swapAmount,
        uint256 _minOutAmount
    )
        internal
        virtual
        returns (uint256)
    {}

    function _withdrawPendleLPs(
        uint256 _nftId,
        uint256 _lendingShares
    )
        internal
        virtual
        returns (uint256 withdrawnLpsAmount)
    {
        return IPendleChild(PENDLE_CHILD).withdrawExactShares(
            _withdrawExactShares(
                _nftId,
                PENDLE_CHILD,
                _lendingShares
            )
        );
    }

    function _withdrawExactShares(
        uint256 _nftId,
        address _token,
        uint256 _lendingShares
    )
        internal
        virtual
        returns (uint256 withdrawnAmount)
    {
        return WISE_LENDING.withdrawExactShares(
            _nftId,
            _token,
            _lendingShares
        );
    }

    function _paybackExactShares(
        bool _isAave,
        uint256 _nftId,
        uint256 _borrowShares
    )
        internal
        virtual
    {
        if (_isAave == true) {
            AAVE_HUB.paybackExactShares(
                _nftId,
                FARM_ASSET,
                _borrowShares
            );

            return;
        }

        WISE_LENDING.paybackExactShares(
            _nftId,
            FARM_ASSET,
            _borrowShares
        );
    }

    /**
     * @dev Internal wrapper function for a closing route
     * which returns {ENTRY_ASSET} to the owner in the end.
     */
    function _closingRouteToken(
        uint256 _tokenAmount,
        uint256 _totalDebtBalancer,
        address _caller
    )
        internal
        virtual
    {
        if (FARM_ASSET == WETH_ADDRESS) {
            _wrapETH(
                _tokenAmount
            );
        }

        address extraPoolAddress = address(UNISWAP_V2_POOL) == address(0x0)
            ? address(UNISWAP_V3_POOL)
            : address(UNISWAP_V2_POOL);

        _safeTransfer(
            FARM_ASSET,
            msg.sender != BALANCER_ADDRESS
                ? extraPoolAddress
                : BALANCER_ADDRESS,
            _totalDebtBalancer
        );

        _safeTransfer(
            FARM_ASSET,
            _caller,
            _tokenAmount - _totalDebtBalancer
        );
    }

    /**
     * @dev Internal wrapper function for a closing route
     * which returns ETH to the owner in the end.
     */
    function _closingRouteETH(
        uint256 _ethAmount,
        uint256 _totalDebtBalancer,
        address _caller
    )
        internal
        virtual
    {
        _wrapETH(
            _totalDebtBalancer
        );

        _safeTransfer(
            FARM_ASSET,
            msg.sender != BALANCER_ADDRESS
                ? address(UNISWAP_V2_POOL)
                : BALANCER_ADDRESS,
            _totalDebtBalancer
        );

        _sendValue(
            _caller,
            _ethAmount - _totalDebtBalancer
        );
    }

    function _logicOpenPosition(
        bytes memory _callData,
        bool _isAave,
        uint256 _nftId,
        uint256 _depositAmount,
        uint256 _totalDebtBalancer,
        uint256 _allowedSpread
    )
        internal
        virtual
    {}

    function _borrowExactAmount(
        bool _isAave,
        uint256 _nftId,
        uint256 _totalDebtBalancer
    )
        internal
        virtual
    {
        if (_isAave == true) {
            AAVE_HUB.borrowExactAmount(
                _nftId,
                FARM_ASSET,
                _totalDebtBalancer
            );

            return;
        }

        WISE_LENDING.borrowExactAmount(
            _nftId,
            FARM_ASSET,
            _totalDebtBalancer
        );
    }

    /**
     * @dev Internal function summarizing liquidation
     * checks and interface call for core liquidation
     * from wise lending.
     */
    function _coreLiquidation(
        uint256 _nftId,
        uint256 _nftIdLiquidator,
        uint256 _shareAmountToPay
    )
        internal
        virtual
        returns (
            uint256 paybackAmount,
            uint256 receivingAmount
        )
    {
        _checkLiquidatability(
            _nftId
        );

        address paybackToken = isAave[_nftId] == true
            ? POOL_ASSET_AAVE
            : FARM_ASSET;

        paybackAmount = _getPaybackAmount(
            paybackToken,
            _shareAmountToPay
        );

        uint256 cutoffShares = isAave[_nftId] == true
            ? _getPositionBorrowSharesAave(_nftId)
                * FIFTY_PERCENT
                / PRECISION_FACTOR_E18
            : _getPositionBorrowShares(_nftId)
                * FIFTY_PERCENT
                / PRECISION_FACTOR_E18;

        if (_shareAmountToPay > cutoffShares) {
            revert GenericTooManyShares();
        }

        receivingAmount = WISE_LENDING.coreLiquidationIsolationPools(
            _nftId,
            _nftIdLiquidator,
            msg.sender,
            paybackToken,
            PENDLE_CHILD,
            paybackAmount,
            _shareAmountToPay
        );
    }

    function _checkLiquidatability(
        uint256 _nftId
    )
        internal
        virtual
        view
    {
        if (specialDepegCase == true) {
            return;
        }

        if (_checkDebtRatio(_nftId) == true) {
            revert GenericDebtRatioTooLow();
        }
    }

    function _callPendleRouter(
        bytes memory _callData
    )
        internal
        virtual
        returns (
            bool success,
            bytes memory returnData
        )
    {
        routingOngoing = true;

        (
            success,
            returnData
        ) = address(PENDLE_ROUTER).call(
            _callData
        );

        routingOngoing = false;
    }
}

File 8 of 31 : IPowerFarmsNFTs.sol
// SPDX-License-Identifier: -- WISE --

pragma solidity =0.8.25;

interface IPowerFarmsNFTs {

    function ownerOf(
        uint256 _tokenId
    )
        external
        view
        returns (address);

    function mintKey(
        address _keyOwner,
        uint256 _keyId
    )
        external;

    /**
     * @dev Burns farming NFT
     */
    function burnKey(
        uint256 _keyId
    )
        external;
}

File 9 of 31 : GenericMathLogic.sol
// SPDX-License-Identifier: -- WISE --

pragma solidity =0.8.25;

import "./GenericDeclarations.sol";

abstract contract GenericMathLogic is GenericDeclarations {

    modifier updatePools() {
        _checkReentrancy();
        _updatePools();
        _;
    }

    /**
     * @dev Update logic for pools via wise lending
     * interfaces
     */
    function _updatePools()
        internal
        virtual
    {
        WISE_LENDING.syncManually(
            FARM_ASSET
        );

        WISE_LENDING.syncManually(
            POOL_ASSET_AAVE
        );

        WISE_LENDING.syncManually(
            PENDLE_CHILD
        );
    }

    function _checkReentrancy()
        internal
        virtual
        view
    {
        if (sendingProgress == true) {
            revert GenericAccessDenied();
        }

        if (WISE_LENDING.sendingProgress() == true) {
            revert GenericAccessDenied();
        }

        if (AAVE_HUB.sendingProgressAaveHub() == true) {
            revert GenericAccessDenied();
        }
    }

    /**
     * @dev Internal function getting the
     * borrow shares from position {_nftId}
     * with token {_borrowToken}
     */
    function _getPositionBorrowShares(
        uint256 _nftId
    )
        internal
        virtual
        view
        returns (uint256)
    {
        return WISE_LENDING.getPositionBorrowShares(
            _nftId,
            FARM_ASSET
        );
    }

    /**
     * @dev Internal function getting the
     * borrow shares of aave from position {_nftId}
     * with token {_borrowToken}
     */
    function _getPositionBorrowSharesAave(
        uint256 _nftId
    )
        internal
        virtual
        view
        returns (uint256)
    {
        return WISE_LENDING.getPositionBorrowShares(
            _nftId,
            POOL_ASSET_AAVE
        );
    }

    /**
     * @dev Internal function converting
     * borrow shares into tokens.
     */
    function _getPositionBorrowTokenAmount(
        uint256 _nftId
    )
        internal
        virtual
        view
        returns (uint256 tokenAmount)
    {
        uint256 positionBorrowShares = _getPositionBorrowShares(
            _nftId
        );

        if (positionBorrowShares > 0) {
            tokenAmount = _getPaybackAmount(
                FARM_ASSET,
                positionBorrowShares
            );
        }
    }

    function _getPaybackAmount(
        address _poolToken,
        uint256 _borrowShares
    )
        internal
        virtual
        view
        returns (uint256 tokenAmount)
    {
        return WISE_LENDING.paybackAmount(
            _poolToken,
            _borrowShares
        );
    }

    function _getPositionBorrowTokenAmountAave(
        uint256 _nftId
    )
        internal
        virtual
        view
        returns (uint256 tokenAmountAave)
    {
        uint256 positionBorrowSharesAave = _getPositionBorrowSharesAave(
            _nftId
        );

        if (positionBorrowSharesAave == 0) {
            return 0;
        }

        tokenAmountAave = _getPaybackAmount(
            POOL_ASSET_AAVE,
            positionBorrowSharesAave
        );
    }
    /**
     * @dev Internal function getting the
     * lending shares from position {_nftId}
     * with token {_borrowToken}
     */
    function _getPositionLendingShares(
        uint256 _nftId
    )
        internal
        virtual
        view
        returns (uint256)
    {
        return WISE_LENDING.getPositionLendingShares(
            _nftId,
            PENDLE_CHILD
        );
    }

    /**
     * @dev Internal function converting
     * lending shares into tokens.
     */
    function _getPostionCollateralTokenAmount(
        uint256 _nftId
    )
        internal
        virtual
        view
        returns (uint256)
    {
        return _getCashoutAmount(
            {
                _poolToken: PENDLE_CHILD,
                _shares: _getPositionLendingShares(
                    _nftId
                )
            }
        );
    }

    /**
     * @dev Read function returning the total
     * borrow amount in ETH from postion {_nftId}
     */
    function getPositionBorrowETH(
        uint256 _nftId
    )
        public
        virtual
        view
        returns (uint256)
    {
        uint256 borrowTokenAmount;
        uint256 borrowShares = _getPositionBorrowShares(
            _nftId
        );

        if (borrowShares > 0) {
            borrowTokenAmount = _getPositionBorrowTokenAmount(
                _nftId
            );
        }

        uint256 borrowSharesAave = _getPositionBorrowSharesAave(
            _nftId
        );

        uint256 borrowTokenAmountAave;

        if (borrowSharesAave > 0) {
            borrowTokenAmountAave = _getPositionBorrowTokenAmountAave(
                _nftId
            );
        }

        uint256 tokenValueEth;

        if (borrowShares > 0) {
            tokenValueEth = _getTokensInETH(
                FARM_ASSET,
                borrowTokenAmount
            );
        }

        if (borrowTokenAmountAave == 0) {
            return tokenValueEth;
        }

        uint256 tokenValueAaveEth = _getTokensInETH(
            POOL_ASSET_AAVE,
            borrowTokenAmountAave
        );

        return tokenValueEth + tokenValueAaveEth;
    }

    /**
     * @dev Read function returning the total
     * lending amount in ETH from postion {_nftId}
     */
    function getTotalWeightedCollateralETH(
        uint256 _nftId
    )
        public
        virtual
        view
        returns (uint256)
    {
        return _getTokensInETH(
            PENDLE_CHILD,
            _getPostionCollateralTokenAmount(_nftId)
        )
            * collateralFactor
            / PRECISION_FACTOR_E18;
    }

    function _getTokensInETH(
        address _tokenAddress,
        uint256 _tokenAmount
    )
        internal
        virtual
        view
        returns (uint256)
    {
        return ORACLE_HUB.getTokensInETH(
            _tokenAddress,
            _tokenAmount
        );
    }

    function _getEthInTokens(
        address _tokenAddress,
        uint256 _ethAmount
    )
        internal
        virtual
        view
        returns (uint256)
    {
        return ORACLE_HUB.getTokensFromETH(
            _tokenAddress,
            _ethAmount
        );
    }

    function getLeverageAmount(
        uint256 _initialAmount,
        uint256 _leverage
    )
        public
        pure
        virtual
        returns (uint256)
    {
        return _initialAmount
            * _leverage
            / PRECISION_FACTOR_E18;
    }

    /**
     * @dev Internal function with math logic for approximating
     * the net APY for the postion aftrer creation.
     */
    function _getApproxNetAPY(
        uint256 _initialAmount,
        uint256 _leverage,
        uint256 _wstETHAPY,
        bool _isAave
    )
        internal
        virtual
        view
        returns (
            uint256,
            bool
        )
    {
        if (_leverage < PRECISION_FACTOR_E18) {
            return (
                0,
                false
            );
        }

        uint256 leveragedAmount = getLeverageAmount(
            _initialAmount,
            _leverage
        );

        uint256 flashloanAmount = leveragedAmount
            - _initialAmount;

        uint256 newBorrowRate = _getNewBorrowRate(
            flashloanAmount,
            _isAave
        );

        uint256 leveragedPositivAPY = _wstETHAPY
            * _leverage
            / PRECISION_FACTOR_E18;

        uint256 leveragedNegativeAPY = newBorrowRate
            * (_leverage - PRECISION_FACTOR_E18)
            / PRECISION_FACTOR_E18;

        bool isPositive = leveragedPositivAPY >= leveragedNegativeAPY;

        uint256 netAPY = isPositive == true
            ? leveragedPositivAPY - leveragedNegativeAPY
            : leveragedNegativeAPY - leveragedPositivAPY;

        return (
            netAPY,
            isPositive
        );
    }

    function _isOutOfRangeAmount(
        uint256 _lpWithdrawAmount
    )
        internal
        virtual
        view
        returns (bool)
    {
        MarketState memory marketState = PENDLE_MARKET.readState(
            address(PENDLE_MARKET)
        );

        (
            ,
            uint256 userSy,
            uint256 userPt
        )
            = _getUserAssetInfo(
                _lpWithdrawAmount,
                uint256(marketState.totalLp),
                uint256(marketState.totalSy),
                uint256(marketState.totalPt)
        );

        uint256 reducedSy = uint256(marketState.totalSy)
            - userSy
            - (
                PT_ORACLE_PENDLE.getPtToSyRate(
                    address(PENDLE_MARKET),
                    1 seconds
                )
                * userPt
                / PRECISION_FACTOR_E18
        );

        uint256 totalAssetsReduced = (
            PENDLE_SY.exchangeRate()
                * reducedSy
                / PRECISION_FACTOR_E18
            + uint256(marketState.totalPt)
        );

        return uint256(marketState.totalPt)
            * PRECISION_FACTOR_E18
            / totalAssetsReduced
            > MAX_PROPORTION;
    }

    function _checkSelector(
        bytes memory _callData
    )
        internal
        pure
        returns (bytes4 selector)
    {
        assembly {
            selector := mload(add(_callData, 32))
        }
    }

    function _getSlicedData(
        bytes memory _callData
    )
        internal
        pure
        virtual
        returns (bytes memory adjustedData)
    {
        adjustedData = new bytes(
            _callData.length - 4
        );

        for (uint i = 0; i < adjustedData.length; i++) {
            adjustedData[i] = _callData[i + 4];
        }
    }

    function _decodeRemoveLiquidity(
        bytes memory _callData
    )
        internal
        pure
        returns (
            address receiver,
            address market,
            uint256 netLpToRemove,
            TokenOutput memory output,
            LimitOrderData memory limit
        )
    {
        bytes memory adjustedData = _getSlicedData(
            _callData
        );

        (
            receiver,
            market,
            netLpToRemove,
            output,
            limit
        ) = abi.decode(
            adjustedData,
            (
                address,
                address,
                uint256,
                TokenOutput,
                LimitOrderData
            )
        );
    }

    function _decodeAddLiquidity(
        bytes memory _callData
    )
        internal
        pure
        returns (
            address receiver,
            address market,
            uint256 minLpOut,
            ApproxParams memory guessPtReceivedFromSy,
            TokenInput memory input,
            LimitOrderData memory limit
        )
    {
        bytes memory adjustedData = _getSlicedData(
            _callData
        );

        (
            receiver,
            market,
            minLpOut,
            guessPtReceivedFromSy,
            input,
            limit
        ) = abi.decode(
            adjustedData,
            (
                address,
                address,
                uint256,
                ApproxParams,
                TokenInput,
                LimitOrderData
            )
        );
    }

    function _verifyCallData(
        bytes memory _callData,
        bool _addLiquidity
    )
        internal
        virtual
    {
        bytes4 expectedSelector = _addLiquidity == true
            ? PENDLE_ROUTER.addLiquiditySingleToken.selector
            : PENDLE_ROUTER.removeLiquiditySingleToken.selector;

        bool verified = _checkSelector(_callData) == expectedSelector;

        if (verified == false) {
            revert GenericInvalidSelector(
                _checkSelector(_callData),
                expectedSelector
            );
        }

        if (_addLiquidity == true) {
            (
                address receiverAddLiq,
                address marketAddLiq,
                uint256 minLpOut,
                ApproxParams memory guessPtReceivedFromSy,
                TokenInput memory input,
                LimitOrderData memory limitAddLiq
            ) = _decodeAddLiquidity(
                _callData
            );

            _verifyDecodedAddLiquidity(
                receiverAddLiq,
                marketAddLiq,
                minLpOut,
                guessPtReceivedFromSy,
                input,
                limitAddLiq
            );

            return;
        }

        (
            address receiver,
            address market,
            uint256 netLpToRemove,
            TokenOutput memory output,
            LimitOrderData memory limit
        ) = _decodeRemoveLiquidity(
            _callData
        );

        _verifyDecodedRemoveLiquidity(
            receiver,
            market,
            netLpToRemove,
            output,
            limit
        );
    }

    function _verifyDecodedRemoveLiquidity(
        address _receiver,
        address _market,
        uint256,
        TokenOutput memory _output,
        LimitOrderData memory _limit
    )
        internal
        virtual
    {
        _verifyStandardData(
            _receiver,
            _market
        );

        _verifyContracts(
            _output.pendleSwap,
            _output.swapData.extRouter,
            _limit.limitRouter
        );

        if (_output.tokenOut != FARM_ASSET) {
            revert GenericWrongTokenOut(
                _output.tokenOut,
                FARM_ASSET
            );
        }
    }

    function _verifyDecodedAddLiquidity(
        address _receiver,
        address _market,
        uint256,
        ApproxParams memory,
        TokenInput memory _input,
        LimitOrderData memory _limit
    )
        internal
        virtual
    {
        _verifyStandardData(
            _receiver,
            _market
        );

        _verifyContracts(
            _input.pendleSwap,
            _input.swapData.extRouter,
            _limit.limitRouter
        );

        if (_input.tokenIn != FARM_ASSET) {
            revert GenericWrongTokenIn(
                _input.tokenIn,
                FARM_ASSET
            );
        }
    }

    function _verifyLimitRouter(
        address _limitRouter
    )
        internal
        virtual
    {
        if (whiteListedExternalContracts[_limitRouter] == false) {
            revert GenericWrongLimitRouter(
                _limitRouter
            );
        }
    }

    function _verifyContracts(
        address _pendleSwap,
        address _extRouter,
        address _limitRouter
    )
        internal
        virtual
    {
        if (whiteListedExternalContracts[_pendleSwap] == false) {
            revert GenericWrongPendleSwap(
                _pendleSwap
            );
        }

        if (_limitRouter > address(0)) {
            _verifyLimitRouter(
                _limitRouter
            );
        }

        if (whiteListedExternalContracts[_extRouter] == false) {
            revert GenericWrongExtRouter(
                _extRouter
            );
        }
    }

    function _verifyStandardData(
        address _receiver,
        address _market
    )
        internal
        virtual
    {
        if (_receiver != address(this)) {
            revert GenericWrongReceiver(
                _receiver,
                address(this)
            );
        }

        if (_market != address(PENDLE_MARKET)) {
            revert GenericWrongMarket(
                _market,
                address(PENDLE_MARKET)
            );
        }
    }

    /**
     * @dev Internal function with math logic for detecting
     * if market is out of range.
     */
    function _isOutOfRange(
        uint256 _nftId
    )
        internal
        virtual
        view
        returns (bool)
    {
        return _isOutOfRangeAmount(
            IPendleChild(PENDLE_CHILD).previewAmountWithdrawShares(
                _getCashoutAmount(
                    PENDLE_CHILD,
                    _getPositionLendingShares(
                        _nftId
                    )
                ),
                IPendleChild(PENDLE_CHILD).underlyingLpAssetsCurrent()
            )
        );
    }

    function _getCashoutAmount(
        address _poolToken,
        uint256 _shares
    )
        internal
        virtual
        view
        returns (uint256)
    {
        return WISE_LENDING.cashoutAmount(
            _poolToken,
            _shares
        );
    }

    function _getUserAssetInfo(
        uint256 _lpToWithdraw,
        uint256 _totalLp,
        uint256 _totalSy,
        uint256 _totalPt
    )
        internal
        virtual
        view
        returns (
            uint256,
            uint256,
            uint256
        )
    {
        uint256 userProportion = _lpToWithdraw
            * PRECISION_FACTOR_E18
            / _totalLp;

        return (
            userProportion,
            userProportion
                * _totalSy
                / PRECISION_FACTOR_E18,
            userProportion
                * _totalPt
                / PRECISION_FACTOR_E18
        );
    }

    /**
     * @dev Internal function with math logic for approximating
     * the new borrow APY.
     */
    function _getNewBorrowRate(
        uint256 _borrowAmount,
        bool _isAave
    )
        internal
        virtual
        view
        returns (uint256)
    {
        address relevantAssetAddress = _isAave == true
            ? POOL_ASSET_AAVE
            : FARM_ASSET;

        uint256 totalPool = WISE_LENDING.getTotalPool(
            relevantAssetAddress
        );

        uint256 pseudoPool = WISE_LENDING.getPseudoTotalPool(
            relevantAssetAddress
        );

        if (totalPool > pseudoPool) {
            return 0;
        }

        uint256 newUtilization = PRECISION_FACTOR_E18 - (PRECISION_FACTOR_E18
            * (totalPool - _borrowAmount)
            / pseudoPool
        );

        uint256 pole = _getBorrowRatesData(
            relevantAssetAddress
        ).pole;

        uint256 mulFactor = _getBorrowRatesData(
            relevantAssetAddress
        ).multiplicativeFactor;

        uint256 baseDivider = pole
            * (pole - newUtilization);

        return mulFactor
            * PRECISION_FACTOR_E18
            * newUtilization
            / baseDivider;
    }

    function _getBorrowRatesData(
        address _poolToken
    )
        internal
        virtual
        view
        returns (BorrowRatesEntry memory)
    {
        return WISE_LENDING.borrowRatesData(
            _poolToken
        );
    }

    /**
     * @dev Internal function checking if a position
     * with {_nftId} has a debt ratio under 100%.
     */
    function _checkDebtRatio(
        uint256 _nftId
    )
        internal
        virtual
        view
        returns (bool)
    {
        uint256 borrowShares = isAave[_nftId]
            ? _getPositionBorrowSharesAave(
                _nftId
            )
            : _getPositionBorrowShares(
                _nftId
            );

        if (borrowShares == 0) {
            return true;
        }

        return getTotalWeightedCollateralETH(_nftId)
            >= getPositionBorrowETH(_nftId);
    }

    /**
     * @dev Internal function checking if the leveraged
     * amount not below {minDepositEthAmount} in value.
     */
    function _notBelowMinDepositAmount(
        uint256 _amount
    )
        internal
        virtual
        view
        returns (bool)
    {
        uint256 equivETH = _getTokensInETH(
            ENTRY_ASSET,
            _amount
        );

        return equivETH >= minDepositEthAmount;
    }
}

File 10 of 31 : GenericDeclarations.sol
// SPDX-License-Identifier: -- WISE --

pragma solidity =0.8.25;

import "../InterfaceHub/IAave.sol";
import "../InterfaceHub/IPendle.sol";
import "../InterfaceHub/IAaveHub.sol";
import "../InterfaceHub/IWiseLending.sol";
import "../InterfaceHub/IWiseSecurity.sol";
import "../InterfaceHub/IPositionNFTs.sol";
import "../InterfaceHub/IWiseOracleHub.sol";
import "../InterfaceHub/IBalancerFlashloan.sol";
import "../InterfaceHub/IUniswapV3.sol";
import "../InterfaceHub/IUniswapV2Pool.sol";
import "../InterfaceHub/IUniswapV3PoolPowerFarm.sol";
import "../InterfaceHub/IUniswapFactory.sol";
import "../InterfaceHub/IOraclePendle.sol";
import "../TransferHub/WrapperHelper.sol";
import "../TransferHub/TransferHelper.sol";
import "../TransferHub/ApprovalHelper.sol";
import "../TransferHub/SendValueHelper.sol";

import "./GenericErrors.sol";

contract GenericDeclarations is
    WrapperHelper,
    TransferHelper,
    ApprovalHelper,
    SendValueHelper
{
    bool public isShutdown;
    bool public allowEnter;

    uint256 public collateralFactor;
    uint256 public minDepositEthAmount;

    uint256 internal MAX_PROPORTION = 96
        * PRECISION_FACTOR_E18
        / 100;

    address public FARM_ASSET;
    address public POOL_ASSET_AAVE;

    address public PENDLE_LIMIT_ROUTER_ADDRESS;

    address public immutable ENTRY_ASSET;
    address public immutable PENDLE_CHILD;

    IAave public immutable AAVE;
    IAaveHub public immutable AAVE_HUB;
    IWiseLending public immutable WISE_LENDING;
    IWiseOracleHub public immutable ORACLE_HUB;
    IWiseSecurity public immutable WISE_SECURITY;
    IBalancerVault public immutable BALANCER_VAULT;
    IPositionNFTs public immutable POSITION_NFT;
    IUniswapV3 public immutable UNISWAP_V3_ROUTER;
    IUniswapV2Pool public UNISWAP_V2_POOL;
    IUniswapV3PoolPowerFarm public UNISWAP_V3_POOL;
    IUniswapFactory public immutable UNISWAP_FACTORY;

    IPendleSy public immutable PENDLE_SY;
    IPendleRouter public PENDLE_ROUTER;
    IPendleMarket public immutable PENDLE_MARKET;
    IPendleRouterStatic public immutable PENDLE_ROUTER_STATIC;
    IOraclePendle public immutable PT_ORACLE_PENDLE;

    address internal immutable WETH_ADDRESS;
    address immutable AAVE_ADDRESS;
    address immutable AAVE_HUB_ADDRESS;
    address immutable AAVE_WETH_ADDRESS;

    address public collateralFactorRole;

    bool public ethBack;
    bool public specialDepegCase;
    bool public routingOngoing;

    struct FarmData {
        uint256 wiseLendingNFT;
        uint256 leverage;
        uint256 amount;
        uint256 amountAfterMintFee;
        uint256 timestamp;
    }

    mapping(uint256 => FarmData) public farmData; //keyId to FarmData
    mapping(uint256 => bool) public isAave; //nftId to bool
    mapping(address => bool) public whiteListedExternalContracts; // whiteList for external contracts to use routing for swaps

    event FarmEntry(
        uint256 indexed keyId,
        uint256 indexed wiseLendingNFT,
        uint256 indexed leverage,
        uint256 amount,
        uint256 amountAfterMintFee,
        uint256 timestamp
    );

    event FarmExit(
        uint256 indexed keyId,
        uint256 indexed wiseLendingNFT,
        uint256 amount,
        uint256 timestamp
    );

    event FarmStatus(
        bool indexed state,
        uint256 timestamp
    );

    event ManualPaybackShares(
        uint256 indexed keyId,
        uint256 indexed wiseLendingNFT,
        uint256 amount,
        uint256 timestamp
    );

    event ManualWithdrawShares(
        uint256 indexed keyId,
        uint256 indexed wiseLendingNFT,
        uint256 amount,
        uint256 timestamp
    );

    event MinDepositChange(
        uint256 minDepositEthAmount,
        uint256 timestamp
    );

    event ETHReceived(
        uint256 amount,
        address from
    );

    event RegistrationFarm(
        uint256 nftId,
        uint256 timestamp
    );

    uint256 internal constant ETH_CHAIN_ID = 1;
    uint256 internal constant ARB_CHAIN_ID = 42161;

    uint256 internal constant FIFTY_PERCENT = 50E16;
    uint256 internal constant PRECISION_FACTOR_E18 = 1E18;
    uint256 internal constant PRECISION_FACTOR_E16 = 1E16;
    uint256 internal constant PRECISION_FACTOR_E18_2X = 2E18;

    uint256 internal constant MAX_AMOUNT = type(uint256).max;
    uint256 internal constant MAX_LEVERAGE = 15 * PRECISION_FACTOR_E18;

    uint24 public constant UNISWAP_V3_FEE = 100;
    address internal constant BALANCER_ADDRESS = 0xBA12222222228d8Ba445958a75a0704d566BF2C8;
    address public constant UNISWAP_FACTORY_V2_ADDRESS = 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f;

    uint256 ongoingFlashAmountV3;

    constructor(
        address _wiseLendingAddress,
        address _pendleChildTokenAddress,
        address _pendleRouter,
        address _entryAsset,
        address _pendleSy,
        address _underlyingMarket,
        address _routerStatic,
        address _dexAddress,
        uint256 _collateralFactor
    )
        WrapperHelper(
            IWiseLending(_wiseLendingAddress).WETH_ADDRESS()
        )
    {
        PENDLE_ROUTER_STATIC = IPendleRouterStatic(
            _routerStatic
        );

        PENDLE_MARKET = IPendleMarket(
            _underlyingMarket
        );

        PENDLE_SY = IPendleSy(
            _pendleSy
        );

        PENDLE_ROUTER = IPendleRouter(
            _pendleRouter
        );

        UNISWAP_V3_ROUTER = IUniswapV3(
            _dexAddress
        );

        if (block.chainid == ETH_CHAIN_ID) {
            UNISWAP_FACTORY = IUniswapFactory(
                UNISWAP_FACTORY_V2_ADDRESS
            );
        }

        ENTRY_ASSET = _entryAsset;
        PENDLE_CHILD = _pendleChildTokenAddress;

        WISE_LENDING = IWiseLending(
            _wiseLendingAddress
        );

        ORACLE_HUB = IWiseOracleHub(
            WISE_LENDING.WISE_ORACLE()
        );

        BALANCER_VAULT = IBalancerVault(
            BALANCER_ADDRESS
        );

        WISE_SECURITY = IWiseSecurity(
            WISE_LENDING.WISE_SECURITY()
        );

        WETH_ADDRESS = WISE_LENDING.WETH_ADDRESS();

        AAVE_HUB = IAaveHub(
            WISE_SECURITY.AAVE_HUB()
        );

        AAVE_ADDRESS = AAVE_HUB.AAVE_ADDRESS();

        AAVE = IAave(
            AAVE_ADDRESS
        );

        AAVE_HUB_ADDRESS = address(
            AAVE_HUB
        );

        POSITION_NFT = IPositionNFTs(
            WISE_LENDING.POSITION_NFT()
        );

        collateralFactor = _collateralFactor;

        AAVE_WETH_ADDRESS = AAVE_HUB.aaveTokenAddress(
            AAVE_HUB.WETH_ADDRESS()
        );

        PT_ORACLE_PENDLE = IOraclePendle(
            0x1Fd95db7B7C0067De8D45C0cb35D59796adfD187
        );

        PENDLE_LIMIT_ROUTER_ADDRESS = 0x000000000000c9B3E2C3Ec88B1B4c0cD853f4321;

        minDepositEthAmount = 0.03 ether;

        // @TODO - REDO - make parameter driven avoid if conditon
        if (block.chainid == ETH_CHAIN_ID) {
            minDepositEthAmount = 3 ether;

            PT_ORACLE_PENDLE = IOraclePendle(
                0x66a1096C6366b2529274dF4f5D8247827fe4CEA8
            );
        }
    }

    function changeUniV3Pool(
        address _poolAddress
    )
        external
        virtual
    {}

    function doApprovals()
        external
        virtual
    {
        _doApprovals(
            address(WISE_LENDING)
        );
    }

    function _doApprovals(
        address _wiseLendingAddress
    )
        internal
        virtual
    {}

    modifier isActive()
    {
        _isActive();
        _;
    }

    modifier routingOngoingCheck()
    {
        _routingOngoingCheck();
        _;
    }

    function _routingOngoingCheck()
        internal
        virtual
    {
        if (routingOngoing == true) {
            revert GenericRoutingOngoing();
        }
    }

    function _isActive()
        internal
        virtual
        view
    {
        if (isShutdown == true) {
            revert GenericDeactivated();
        }
    }

    modifier onlyCollateralFactorRole() {
        _onlyCollateralFactorRole();
        _;
    }

    function _onlyCollateralFactorRole()
        internal
        virtual
    {
        if (msg.sender != collateralFactorRole) {
            revert GenericAccessDenied();
        }
    }
}

File 11 of 31 : IAave.sol
// SPDX-License-Identifier: -- WISE --

pragma solidity =0.8.25;

interface IAave {

    struct ReserveData {

        // Stores the reserve configuration
        ReserveConfigurationMap configuration;

        // Liquidity index. Expressed in ray
        uint128 liquidityIndex;

        // Current supply rate. Expressed in ray
        uint128 currentLiquidityRate;

        // Variable borrow index. Expressed in ray
        uint128 variableBorrowIndex;

        // Current variable borrow rate. Expressed in ray
        uint128 currentVariableBorrowRate;

        // Current stable borrow rate. Expressed in ray
        uint128 currentStableBorrowRate;

        // Timestamp of last update
        uint40 lastUpdateTimestamp;

        // Id of the reserve.
        uint16 id;

        // aToken address
        address aTokenAddress;

        // stableDebtToken address
        address stableDebtTokenAddress;

        // VariableDebtToken address
        address variableDebtTokenAddress;

        // Address of the interest rate strategy
        address interestRateStrategyAddress;

        // Current treasury balance, scaled
        uint128 accruedToTreasury;

        // Outstanding unbacked aTokens minted through the bridging feature
        uint128 unbacked;

        // Outstanding debt borrowed against this asset in isolation mode
        uint128 isolationModeTotalDebt;
    }

    struct ReserveConfigurationMap {
        uint256 data;
    }

    function supply(
        address _token,
        uint256 _amount,
        address _owner,
        uint16 _referralCode
    )
        external;

    function withdraw(
        address _token,
        uint256 _amount,
        address _recipient
    )
        external
        returns (uint256);

    function getReserveData(
        address asset
    )
        external
        view
        returns (ReserveData memory);

}

File 12 of 31 : IPendle.sol
// SPDX-License-Identifier: -- WISE --

pragma solidity =0.8.25;

import {IERC20 as IERC20A} from "./IERC20.sol";

struct Order {
    uint256 salt;
    uint256 expiry;
    uint256 nonce;
    IPLimitOrderType.OrderType orderType;
    address token;
    address YT;
    address maker;
    address receiver;
    uint256 makingAmount;
    uint256 lnImpliedRate;
    uint256 failSafeRate;
    bytes permit;
}

struct FillOrderParams {
    Order order;
    bytes signature;
    uint256 makingAmount;
}

struct TokenOutput {
    // TOKEN DATA
    address tokenOut;
    uint256 minTokenOut;
    address tokenRedeemSy;
    // AGGREGATOR DATA
    address pendleSwap;
    SwapData swapData;
}

struct LimitOrderData {
    address limitRouter;
    uint256 epsSkipMarket; // only used for swap
        // operations, will be ignored otherwise
    FillOrderParams[] normalFills;
    FillOrderParams[] flashFills;
    bytes optData;
}

struct TokenInput {
    // TOKEN DATA
    address tokenIn;
    uint256 netTokenIn;
    address tokenMintSy;
    // AGGREGATOR DATA
    address pendleSwap;
    SwapData swapData;
}

enum SwapType {
    NONE,
    KYBERSWAP,
    ONE_INCH,
    // ETH_WETH not used in Aggregator
    ETH_WETH
}

struct SwapData {
    SwapType swapType;
    address extRouter;
    bytes extCalldata;
    bool needScale;
}

struct MarketStorage {
    int128 totalPt;
    int128 totalSy;
    uint96 lastLnImpliedRate;
    uint16 observationIndex;
    uint16 observationCardinality;
    uint16 observationCardinalityNext;
}

struct FillResults {
    uint256 totalMaking;
    uint256 totalTaking;
    uint256 totalFee;
    uint256 totalNotionalVolume;
    uint256[] netMakings;
    uint256[] netTakings;
    uint256[] netFees;
    uint256[] notionalVolumes;
}

struct MarketState {
    int256 totalPt;
    int256 totalSy;
    int256 totalLp;
    address treasury;
    int256 scalarRoot;
    uint256 expiry;
    uint256 lnFeeRateRoot;
    uint256 reserveFeePercent;
    uint256 lastLnImpliedRate;
}

struct LockedPosition {
    uint128 amount;
    uint128 expiry;
}

struct UserReward {
    uint128 index;
    uint128 accrued;
}

struct ApproxParams {
    uint256 guessMin;
    uint256 guessMax;
    uint256 guessOffchain;
    uint256 maxIteration;
    uint256 eps;
}

interface IPendleSy {

    function decimals()
        external
        view
        returns (uint8);

    function previewDeposit(
        address _tokenIn,
        uint256 _amountTokenToDeposit
    )
        external
        view
        returns (uint256 sharesAmount);

    function deposit(
        address _receiver,
        address _tokenIn,
        uint256 _amountTokenToDeposit,
        uint256 _minSharesOut
    )
        external
        returns (uint256 sharesAmount);

    function exchangeRate()
        external
        view
        returns (uint256);

    function redeem(
        address _receiver,
        uint256 _amountSharesToRedeem,
        address _tokenOut,
        uint256 _minTokenOut,
        bool _burnFromInternalBalance
    )
        external
        returns (uint256 amountTokenOut);
}

interface IPendleYt {

    function mintPY(
        address _receiverPT,
        address _receiverYT
    )
        external
        returns (uint256 pyAmount);

    function redeemPY(
        address _receiver
    )
        external
        returns (uint256);

    function redeemDueInterestAndRewards(
        address _user,
        bool _redeemInterest,
        bool _redeemRewards
    )
        external
        returns (
            uint256 interestOut,
            uint256[] memory rewardsOut
        );

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

    function userReward(
        address _token,
        address _user
    )
        external
        view
        returns (UserReward memory);

    function userInterest(
        address user
    )
        external
        view
        returns (
            uint128 lastPYIndex,
            uint128 accruedInterest
        );

    function pyIndexStored()
        external
        view
        returns (uint256);
}

interface IPendleMarket {

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    )
        external;

    function readTokens()
        external
        view
        returns (
            address SY,
            address PT,
            address YT
        );

    function activeBalance(
        address _user
    )
        external
        view
        returns (uint256);

    function transferFrom(
        address _from,
        address _to,
        uint256 _amount
    )
        external;

    function balanceOf(
        address _user
    )
        external
        view
        returns (uint256);

    function isExpired()
        external
        view
        returns (bool);

    function decimals()
        external
        view
        returns (uint8);

    function increaseObservationsCardinalityNext(
        uint16 _newObservationCardinalityNext
    )
        external;

    function swapExactPtForSy(
        address receiver,
        uint256 exactPtIn,
        bytes calldata data
    )
        external
        returns (
            uint256 netSyOut,
            uint256 netSyFee
        );

    function _storage()
        external
        view
        returns (MarketStorage memory);

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

    function readState(
        address _router
    )
        external
        view
        returns (MarketState memory marketState);

    function mint(
        address _receiver,
        uint256 _netSyDesired,
        uint256 _netPtDesired
    )
        external
        returns (uint256[3] memory);

    function burn(
        address _receiverAddressSy,
        address _receiverAddressPt,
        uint256 _lpToBurn
    )
        external
        returns (
            uint256 syOut,
            uint256 ptOut
        );

    function redeemRewards(
        address _user
    )
        external
        returns (uint256[] memory);

    function totalSupply()
        external
        view
        returns (uint256);

    function userReward(
        address _token,
        address _user
    )
        external
        view
        returns (UserReward memory);
}

interface IPendleChild {

    function underlyingLpAssetsCurrent()
        external
        view
        returns (uint256);

    function totalLpAssets()
        external
        view
        returns (uint256);

    function totalSupply()
        external
        view
        returns (uint256);

    function previewUnderlyingLpAssets()
        external
        view
        returns (uint256);

    function previewMintShares(
        uint256 _underlyingAssetAmount,
        uint256 _underlyingLpAssetsCurrent
    )
        external
        view
        returns (uint256);

    function previewAmountWithdrawShares(
        uint256 _shares,
        uint256 _underlyingLpAssetsCurrent
    )
        external
        view
        returns (uint256);

    function previewBurnShares(
        uint256 _underlyingAssetAmount,
        uint256 _underlyingLpAssetsCurrent
    )
        external
        view
        returns (uint256);

    function depositExactAmount(
        uint256 _amount
    )
        external
        returns (
            uint256,
            uint256
        );

    function withdrawExactShares(
        uint256 _shares
    )
        external
        returns (uint256);
}

interface IPendleLock {

    function increaseLockPosition(
        uint128 _additionalAmountToLock,
        uint128 _newExpiry
    )
        external
        returns (uint128 newVeBalance);

    function withdraw()
        external
        returns (uint128);

    function positionData(
        address _user
    )
        external
        view
        returns (LockedPosition memory);

    function getBroadcastPositionFee(
        uint256[] calldata _chainIds
    )
        external
        view
        returns (uint256);
}

interface IPendleVoteRewards {
    function claimRetail(
        address _user,
        uint256 _amount,
        bytes32[] calldata _merkleProof
    )
        external
        returns (uint256);
}

interface IPendleVoter {
    function vote(
        address[] memory _pools,
        uint64[] memory _weights
    )
        external;
}

interface IPLimitOrderType {

    enum OrderType {
        SY_FOR_PT,
        PT_FOR_SY,
        SY_FOR_YT,
        YT_FOR_SY
    }

    // Fixed-size order part with core information
    struct StaticOrder {
        uint256 salt;
        uint256 expiry;
        uint256 nonce;
        OrderType orderType;
        address token;
        address YT;
        address maker;
        address receiver;
        uint256 makingAmount;
        uint256 lnImpliedRate;
        uint256 failSafeRate;
    }
}

interface IPendleRouter {

    function removeLiquiditySingleToken(
        address receiver,
        address market,
        uint256 netLpToRemove,
        TokenOutput calldata output,
        LimitOrderData calldata limit
    )
        external
        returns (
            uint256 netTokenOut,
            uint256 netSyFee,
            uint256 netSyInterm
        );

    function swapTokenToToken(
        address receiver,
        uint256 minTokenOut,
        TokenInput memory inp
    )
        external
        payable
        returns (uint256 netTokenOut);

    function addLiquiditySingleToken(
        address receiver,
        address market,
        uint256 minLpOut,
        ApproxParams memory guessPtReceivedFromSy,
        TokenInput memory input,
        LimitOrderData memory limit
    )
        external
        payable
        returns (
            uint256 netLpOut,
            uint256 netSyFee,
            uint256 netSyInterm
        );

    function swapSyForExactYt(
        address _receiver,
        address _market,
        uint256 _exactYtOut,
        uint256 _maxSyIn
    )
        external
        returns (
            uint256 netSyIn,
            uint256 netSyFee
        );

    function swapExactSyForYt(
        address _receiver,
        address _market,
        uint256 _exactSyIn,
        uint256 _minYtOut
    )
        external
        returns (
            uint256 netYtOut,
            uint256 netSyFee
        );

    function swapSyForExactPt(
        address _receiver,
        address _market,
        uint256 _exactPtOut,
        uint256 _maxSyIn
    )
        external
        returns (
            uint256 netSyIn,
            uint256 netSyFee
        );

    function swapExactSyForPt(
        address _receiver,
        address _market,
        uint256 _exactSyIn,
        uint256 _minPtOut
    )
        external
        returns (
            uint256 netPtOut,
            uint256 netSyFee
        );

    function removeLiquiditySingleSy(
        address _receiver,
        address _market,
        uint256 _netLpToRemove,
        uint256 _minSyOut
    )
        external
        returns (
            uint256 netSyOut,
            uint256 netSyFee
        );

    function addLiquiditySingleSy(
        address _receiver,
        address _market,
        uint256 _netSyIn,
        uint256 _minLpOut,
        ApproxParams calldata _guessPtReceivedFromSy
    )
        external
        returns (
            uint256 netLpOut,
            uint256 netSyFee
        );
}

interface IPendleRouterStatic {

    function addLiquiditySingleSyStatic(
        address _market,
        uint256 _netSyIn
    )
        external
        view
        returns (
            uint256 netLpOut,
            uint256 netPtFromSwap,
            uint256 netSyFee,
            uint256 priceImpact,
            uint256 exchangeRateAfter,
            uint256 netSyToSwap
        );

    function swapExactPtForSyStatic(
        address _market,
        uint256 _exactPtIn
    )
        external
        view
        returns (
            uint256 netSyOut,
            uint256 netSyFee,
            uint256 priceImpact,
            uint256 exchangeRateAfter
        );
}

File 13 of 31 : IAaveHub.sol
// SPDX-License-Identifier: -- WISE --

pragma solidity =0.8.25;

interface IAaveHub {

    function AAVE_ADDRESS()
        external
        view
        returns (address);

    function WETH_ADDRESS()
        external
        view
        returns (address);

    function aaveTokenAddress(
        address _underlyingToken
    )
        external
        view
        returns (address);

    function setAaveTokenAddress(
        address _underlyingToken,
        address _aaveToken
    )
        external;

    function borrowExactAmount(
        uint256 _nftId,
        address _underlyingAsset,
        uint256 _borrowAmount
    )
        external
        returns (uint256);

    function paybackExactShares(
        uint256 _nftId,
        address _underlyingAsset,
        uint256 _shares
    )
        external
        returns (uint256);

    function paybackExactAmountETH(
        uint256 _nftId
    )
        external
        payable
        returns (uint256);

    function paybackExactAmount(
        uint256 _nftId,
        address _underlyingAsset,
        uint256 _shares
    )
        external
        returns (uint256);

    function depositExactAmount(
        uint256 _nftId,
        address _underlyingAsset,
        uint256 _amount
    )
        external
        returns (uint256);

    function depositExactAmountETH(
        uint256 _nftId
    )
        external
        payable
        returns (uint256);

    function depositExactAmountETHMint()
        external
        payable
        returns (uint256);

    function withdrawExactShares(
        uint256 _nftId,
        address _underlyingAsset,
        uint256 _shares
    )
        external
        returns (uint256);

    function withdrawExactAmount(
        uint256 _nftId,
        address _token,
        uint256 _amount
    )
        external
        returns (uint256);

    function sendingProgressAaveHub()
        external
        view
        returns (bool);

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

File 14 of 31 : IWiseLending.sol
// SPDX-License-Identifier: -- WISE --

pragma solidity =0.8.25;

struct GlobalPoolEntry {
    uint256 totalPool;
    uint256 utilization;
    uint256 totalBareToken;
    uint256 poolFee;
}

struct BorrowPoolEntry {
    bool allowBorrow;
    uint256 pseudoTotalBorrowAmount;
    uint256 totalBorrowShares;
    uint256 borrowRate;
}

struct LendingPoolEntry {
    uint256 pseudoTotalPool;
    uint256 totalDepositShares;
    uint256 collateralFactor;
}

struct PoolEntry {
    uint256 totalPool;
    uint256 utilization;
    uint256 totalBareToken;
    uint256 poolFee;
}

struct BorrowRatesEntry {
    uint256 pole;
    uint256 deltaPole;
    uint256 minPole;
    uint256 maxPole;
    uint256 multiplicativeFactor;
}

interface IWiseLending {

    function borrowRatesData(
        address _pooToken
    )
        external
        view
        returns (BorrowRatesEntry memory);

    function newBorrowRate(
        address _poolToken
    )
        external;

    function calculateBorrowShares(
        address _poolToken,
        uint256 _amount,
        bool _maxSharePrice
    )
        external
        view
        returns (uint256);

    function borrowPoolData(
        address _poolToken
    )
        external
        view
        returns (BorrowPoolEntry memory);

    function lendingPoolData(
        address _poolToken
    )
        external
        view
        returns (LendingPoolEntry memory);

    function getPositionBorrowShares(
        uint256 _nftId,
        address _poolToken
    )
        external
        view
        returns (uint256);

    function getTimeStamp(
        address _poolToken
    )
        external
        view
        returns (uint256);

    function getPureCollateralAmount(
        uint256 _nftId,
        address _poolToken
    )
        external
        view
        returns (uint256);

    function isUncollateralized(
        uint256 _nftId,
        address _poolToken
    )
        external
        view
        returns (bool);

    function verifiedIsolationPool(
        address _poolAddress
    )
        external
        view
        returns (bool);

    function positionLocked(
        uint256 _nftId
    )
        external
        view
        returns (bool);

    function getTotalBareToken(
        address _poolToken
    )
        external
        view
        returns (uint256);

    function maxDepositValueToken(
        address _poolToken
    )
        external
        view
        returns (uint256);

    function master()
        external
        view
        returns (address);

    function WETH_ADDRESS()
        external
        view
        returns (address);

    function WISE_ORACLE()
        external
        view
        returns (address);

    function POSITION_NFT()
        external
        view
        returns (address);

    function FEE_MANAGER()
        external
        view
        returns (address);

    function WISE_SECURITY()
        external
        view
        returns (address);

    function lastUpdated(
        address _poolAddress
    )
        external
        view
        returns (uint256);

    function isolationPoolRegistered(
        uint256 _nftId,
        address _isolationPool
    )
        external
        view
        returns (bool);

    function calculateLendingShares(
        address _poolToken,
        uint256 _amount,
        bool _maxSharePrice
    )
        external
        view
        returns (uint256);

    function pureCollateralAmount(
        uint256 _nftId,
        address _poolToken
    )
        external
        returns (uint256);

    function getTotalPool(
        address _poolToken
    )
        external
        view
        returns (uint256);

    function depositExactAmount(
        uint256 _nftId,
        address _poolToken,
        uint256 _amount
    )
        external
        returns (uint256);

    function withdrawOnBehalfExactAmount(
        uint256 _nftId,
        address _poolToken,
        uint256 _amount
    )
        external
        returns (uint256);

    function syncManually(
        address _poolToken
    )
        external;

    function withdrawOnBehalfExactShares(
        uint256 _nftId,
        address _poolToken,
        uint256 _shares
    )
        external
        returns (uint256);

    function borrowOnBehalfExactAmount(
        uint256 _nftId,
        address _poolToken,
        uint256 _amount
    )
        external
        returns (uint256);

    function borrowExactAmount(
        uint256 _nftId,
        address _poolToken,
        uint256 _amount
    )
        external
        returns (uint256);

    function paybackExactAmountETH(
        uint256 _nftId
    )
        external
        payable
        returns (uint256);

    function solelyDeposit(
        uint256 _nftId,
        address _poolToken,
        uint256 _amount
    )
        external;

    function paybackExactAmount(
        uint256 _nftId,
        address _poolToken,
        uint256 _amount
    )
        external
        returns (uint256);

    function paybackExactShares(
        uint256 _nftId,
        address _poolToken,
        uint256 _shares
    )
        external
        returns (uint256);

    function setPoolFee(
        address _poolToken,
        uint256 _newFee
    )
        external;

    function getPositionLendingShares(
        uint256 _nftId,
        address _poolToken
    )
        external
        view
        returns (uint256);

    function collateralizeDeposit(
        uint256 _nftId,
        address _poolToken
    )
        external;

    function approve(
        address _spender,
        address _poolToken,
        uint256 _amount
    )
        external;

    function withdrawExactShares(
        uint256 _nftId,
        address _poolToken,
        uint256 _shares
    )
        external
        returns (uint256);

    function withdrawExactAmount(
        uint256 _nftId,
        address _poolToken,
        uint256 _amount
    )
        external
        returns (uint256);

    function poolTokenAddresses()
        external
        returns (address[] memory);

    function corePaybackFeeManager(
        address _poolToken,
        uint256 _nftId,
        uint256 _amount,
        uint256 _shares
    )
        external;

    function sendingProgress()
        external
        view
        returns (bool);

    function depositExactAmountETH(
        uint256 _nftId
    )
        external
        payable
        returns (uint256);

    function coreLiquidationIsolationPools(
        uint256 _nftId,
        uint256 _nftIdLiquidator,
        address _caller,
        address _tokenToPayback,
        address _tokenToRecieve,
        uint256 _paybackAmount,
        uint256 _shareAmountToPay
    )
        external
        returns (uint256 reveiveAmount);

    function preparePool(
        address _poolToken
    )
        external;

    function getPositionBorrowTokenLength(
        uint256 _nftId
    )
        external
        view
        returns (uint256);

    function getPositionBorrowTokenByIndex(
        uint256 _nftId,
        uint256 _index
    )
        external
        view
        returns (address);

    function getPositionLendingTokenByIndex(
        uint256 _nftId,
        uint256 _index
    )
        external
        view
        returns (address);

    function getPositionLendingTokenLength(
        uint256 _nftId
    )
        external
        view
        returns (uint256);

    function globalPoolData(
        address _poolToken
    )
        external
        view
        returns (GlobalPoolEntry memory);


    function getGlobalBorrowAmount(
        address _token
    )
        external
        view
        returns (uint256);

    function getPseudoTotalBorrowAmount(
        address _token
    )
        external
        view
        returns (uint256);

    function getInitialBorrowAmountUser(
        address _user,
        address _token
    )
        external
        view
        returns (uint256);

    function getPseudoTotalPool(
        address _token
    )
        external
        view
        returns (uint256);

    function getInitialDepositAmountUser(
        address _user,
        address _token
    )
        external
        view
        returns (uint256);

    function getGlobalDepositAmount(
        address _token
    )
        external
        view
        returns (uint256);

    function paybackAmount(
        address _token,
        uint256 _shares
    )
        external
        view
        returns (uint256);

    function getPositionLendingShares(
        address _user,
        address _token
    )
        external
        view
        returns (uint256);

    function cashoutAmount(
        address _poolToken,
        uint256 _shares
    )
        external
        view
        returns (uint256);

    function getTotalDepositShares(
        address _token
    )
        external
        view
        returns (uint256);

    function getTotalBorrowShares(
        address _token
    )
        external
        view
        returns (uint256);

    function checkPositionLocked(
        uint256 _nftId,
        address _caller
    )
        external
        view;

    function checkDeposit(
        uint256 _nftId,
        address _caller,
        address _poolToken,
        uint256 _amount
    )
        external
        view;

    function setRegistrationIsolationPool(
        uint256 _nftId,
        bool _state
    )
        external;
}

File 15 of 31 : IWiseSecurity.sol
// SPDX-License-Identifier: -- WISE --

pragma solidity =0.8.25;

struct CurveSwapStructToken {
    uint256 curvePoolTokenIndexFrom;
    uint256 curvePoolTokenIndexTo;
    uint256 curveMetaPoolTokenIndexFrom;
    uint256 curveMetaPoolTokenIndexTo;
}

struct CurveSwapStructData {
    address curvePool;
    address curveMetaPool;
    bytes swapBytesPool;
    bytes swapBytesMeta;
}

interface IWiseSecurity {

    function checkMinDepositValue(
        address _poolToken,
        uint256 _amount
    )
        external
        view
        returns (bool);

    function overallETHBorrow(
        uint256 _nftId
    )
        external
        view
        returns (uint256 buffer);

    function overallETHCollateralsBoth(
        uint256 _nftId
    )
        external
        view
        returns (uint256 weighted, uint256 unweightedamount);

    function getLiveDebtRatio(
        uint256 _nftId
    )
        external
        view
        returns (uint256);

    function checkHealthState(
        uint256 _nftId,
        bool _isPowerFarm
    )
        external
        view;

    function checkPoolCondition(
        address _token
    )
        external
        view;

    function checkPoolWithMinDeposit(
        address _poolToken,
        uint256 _amount
    )
        external
        view
        returns (bool);

    function overallETHBorrowHeartbeat(
        uint256 _nftId
    )
        external
        view
        returns (uint256 buffer);

    function checksLiquidation(
        uint256 _nftIdLiquidate,
        address _tokenToPayback,
        uint256 _shareAmountToPay
    )
        external
        view;

    function getPositionLendingAmount(
        uint256 _nftId,
        address _poolToken
    )
        external
        view
        returns (uint256);

    function getBorrowRate(
        address _poolToken
    )
        external
        view
        returns (uint256);

    function getPositionBorrowAmount(
        uint256 _nftId,
        address _poolToken
    )
        external
        view
        returns (uint256);

    function overallUSDCollateralsBare(
        uint256 _nftId
    )
        external
        view
        returns (uint256 amount);

    function overallETHCollateralsBare(
        uint256 _nftId
    )
        external
        view
        returns (uint256 amount);

    function FEE_MANAGER()
        external
        view
        returns (address);

    function AAVE_HUB()
        external
        view
        returns (address);

    function curveSecurityCheck(
        address _poolAddress
    )
        external;

    function prepareCurvePools(
        address _poolToken,
        CurveSwapStructData calldata _curveSwapStructData,
        CurveSwapStructToken calldata _curveSwapStructToken
    )
        external;

    function overallETHBorrowBare(
        uint256 _nftId
    )
        external
        view
        returns (uint256 amount);

    function checksWithdraw(
        uint256 _nftId,
        address _caller,
        address _poolToken
    )
        external
        view
        returns (bool);

    function checksBorrow(
        uint256 _nftId,
        address _caller,
        address _poolToken
    )
        external
        view
        returns (bool);

    function checksSolelyWithdraw(
        uint256 _nftId,
        address _caller,
        address _poolToken
    )
        external
        view
        returns (bool);

    function checkOwnerPosition(
        uint256 _nftId,
        address _caller
    )
        external
        view;

    function checksCollateralizeDeposit(
        uint256 _nftIdCaller,
        address _caller,
        address _poolAddress
    )
        external
        view;

    function calculateWishPercentage(
        uint256 _nftId,
        address _receiveToken,
        uint256 _paybackETH,
        uint256 _maxFeeETH,
        uint256 _baseRewardLiquidation
    )
        external
        view
        returns (uint256);

    function checkUncollateralizedDeposit(
        uint256 _nftIdCaller,
        address _poolToken
    )
        external
        view;

    function checkPositionLocked(
        uint256 _nftId,
        address _caller
    )
        external
        view;

    function maxFeeETH()
        external
        view
        returns (uint256);

    function maxFeeFarmETH()
        external
        view
        returns (uint256);

    function baseRewardLiquidation()
        external
        view
        returns (uint256);

    function baseRewardLiquidationFarm()
        external
        view
        returns (uint256);

    function checksRegister(
        uint256 _nftId,
        address _caller
    )
        external
        view;

    function getLendingRate(
        address _poolToken
    )
        external
        view
        returns (uint256);
}

File 16 of 31 : IPositionNFTs.sol
// SPDX-License-Identifier: -- WISE --

pragma solidity =0.8.25;

interface IPositionNFTs {

    function transferFrom(
        address _from,
        address _to,
        uint256 _nftId
    )
        external;

    function ownerOf(
        uint256 _nftId
    )
        external
        view
        returns (address);

    function totalSupply()
        external
        view
        returns (uint256);

    function reserved(
        address _owner
    )
        external
        view
        returns (uint256);

    function reservePosition()
        external;

    function mintPosition()
        external
        returns (uint256);

    function tokenOfOwnerByIndex(
        address _owner,
        uint256 _index
    )
        external
        view
        returns (uint256);

    function walletOfOwner(
        address _owner
    )
        external
        view
        returns (uint256[] memory);

    function mintPositionForUser(
        address _user
    )
        external
        returns (uint256);

    function reservePositionForUser(
        address _user
    )
        external
        returns (uint256);

    function getNextExpectedId()
        external
        view
        returns (uint256);

    function getApproved(
        uint256 _nftId
    )
        external
        view
        returns (address);

    function approve(
        address _to,
        uint256 _nftId
    )
        external;

    function isOwner(
        uint256 _nftId,
        address _caller
    )
        external
        view
        returns (bool);

    function FEE_MANAGER_NFT()
        external
        view
        returns (uint256);
}

File 17 of 31 : IWiseOracleHub.sol
// SPDX-License-Identifier: -- WISE --

pragma solidity =0.8.25;

interface IWiseOracleHub {

    function getTokensPriceFromUSD(
        address _tokenAddress,
        uint256 _usdValue
    )
        external
        view
        returns (uint256);

    function getTokensPriceInUSD(
        address _tokenAddress,
        uint256 _tokenAmount
    )
        external
        view
        returns (uint256);

    function latestResolver(
        address _tokenAddress
    )
        external
        view
        returns (uint256);

    function latestResolverTwap(
        address _tokenAddress
    )
        external
        view
        returns (uint256);

    function getTokensFromUSD(
        address _tokenAddress,
        uint256 _usdValue
    )
        external
        view
        returns (uint256);

    function getTokensFromETH(
        address _tokenAddress,
        uint256 _ethValue
    )
        external
        view
        returns (uint256);

    function getTokensInUSD(
        address _tokenAddress,
        uint256 _amount
    )
        external
        view
        returns (uint256);

    function getTokensInETH(
        address _tokenAddress,
        uint256 _tokenAmount
    )
        external
        view
        returns (uint256);

    function chainLinkIsDead(
        address _tokenAddress
    )
        external
        view
        returns (bool);

    function decimalsUSD()
        external
        pure
        returns (uint8);

    function addOracle(
        address _tokenAddress,
        address _priceFeedAddress,
        address[] calldata _underlyingFeedTokens
    )
        external;

    function recalibrate(
        address _tokenAddress
    )
        external;

    function WETH_ADDRESS()
        external
        view
        returns (address);

    function priceFeed(
        address _tokenAddress
    )
        external
        view
        returns (address);
}

File 18 of 31 : IBalancerFlashloan.sol
// SPDX-License-Identifier: -- WISE --

pragma solidity =0.8.25;

import "../InterfaceHub/IERC20.sol";

interface IBalancerVault {

    /**
     * @dev Performs a 'flash loan', sending tokens to `recipient`, executing the `receiveFlashLoan` hook on it,
     * and then reverting unless the tokens plus a proportional protocol fee have been returned.
     *
     * The `tokens` and `amounts` arrays must have the same length, and each entry in these indicates the loan amount
     * for each token contract. `tokens` must be sorted in ascending order.
     *
     * The 'userData' field is ignored by the Vault, and forwarded as-is to `recipient` as part of the
     * `receiveFlashLoan` call.
     *
     * Emits `FlashLoan` events.
     */
    function flashLoan(
        IFlashLoanRecipient _recipient,
        IERC20[] memory _tokens,
        uint256[] memory _amounts,
        bytes memory _userData
    )
        external;
}

interface IFlashLoanRecipient {

    /**
     * @dev When `flashLoan` is called on the Vault, it invokes the `receiveFlashLoan` hook on the recipient.
     *
     * At the time of the call, the Vault will have transferred `amounts` for `tokens` to the recipient. Before this
     * call returns, the recipient must have transferred `amounts` plus `feeAmounts` for each token back to the
     * Vault, or else the entire flash loan will revert.
     *
     * `userData` is the same value passed in the `IVault.flashLoan` call.
     */
    function receiveFlashLoan(
        IERC20[] memory _tokens,
        uint256[] memory _amounts,
        uint256[] memory _feeAmounts,
        bytes memory _userData
    )
        external;
}

File 19 of 31 : IUniswapV3.sol
// SPDX-License-Identifier: -- WISE --

pragma solidity =0.8.25;

interface IUniswapV3SwapCallback {

    function uniswapV3SwapCallback(
        int256 _amount0Delta,
        int256 _amount1Delta,
        bytes calldata _data
    )
        external;
}

interface IUniswapV3 is IUniswapV3SwapCallback {

    struct ExactInputSingleParams {
        address tokenIn;
        address tokenOut;
        uint24 fee;
        address recipient;
        uint256 deadline;
        uint256 amountIn;
        uint256 amountOutMinimum;
        uint160 sqrtPriceLimitX96;
    }

    struct ExactOutputSingleParams {
        address tokenIn;
        address tokenOut;
        uint24 fee;
        address recipient;
        uint256 deadline;
        uint256 amountOut;
        uint256 amountInMaximum;
        uint160 sqrtPriceLimitX96;
    }

    function exactInputSingle(
        ExactInputSingleParams calldata _params
    )
        external
        payable
        returns (uint256 amountOut);

    function exactOutputSingle(
        ExactOutputSingleParams calldata _params
    )
        external
        payable
        returns (uint256 amountIn);
}

File 20 of 31 : IUniswapV2Pool.sol
// SPDX-License-Identifier: -- WISE --

pragma solidity =0.8.25;

interface IUniswapV2Pool {

    function getReserves()
        external
        view
        returns (
            uint112 reserve0,
            uint112 reserve1,
            uint32 blockTimestampLast
        );

    function token0()
        external
        view
        returns (address);

    function token1()
        external
        view
        returns (address);

    function totalSupply()
        external
        view
        returns (uint);

    function balanceOf(address owner)
        external
        view
        returns (uint);

    function getAmountsOut(
        uint amountIn,
        address[] memory path
    )
        external
        view
        returns (uint[] memory amounts);

    function swapExactTokensForTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    )
        external
        returns (uint[] memory amounts);

    function swap(
        uint amount0Out,
        uint amount1Out,
        address to,
        bytes calldata data
    )
        external;

    function skim(address to)
        external;

    function sync()
        external;

    function initialize(
        address,
        address
    )
        external;
}

File 21 of 31 : IUniswapV3PoolPowerFarm.sol
// SPDX-License-Identifier: -- WISE --

pragma solidity =0.8.25;

interface IUniswapV3PoolPowerFarm {

    function flash(
        address recipient,
        uint256 amount0,
        uint256 amount1,
        bytes calldata data
    )
        external;

    function token0()
        external
        view
        returns (address);

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

File 22 of 31 : IUniswapFactory.sol
// SPDX-License-Identifier: -- WISE --

pragma solidity =0.8.25;

interface IUniswapFactory {

    function getPair(
        address tokenA,
        address tokenB
    )
        external
        view
        returns (address pair);
}

File 23 of 31 : IOraclePendle.sol
// SPDX-License-Identifier: -- WISE --

pragma solidity =0.8.25;

interface IOraclePendle {
    function getOracleState(
        address market,
        uint32 duration
    )
        external
        view
        returns (
            bool increaseCardinalityRequired,
            uint16 cardinalityRequired,
            bool oldestObservationSatisfied
        );

    function getPtToAssetRate(
        address market,
        uint32 duration
    )
        external
        view
        returns (uint256 ptToAssetRate);

    function getPtToSyRate(
        address market,
        uint32 duration
    )
        external
        view
        returns (uint256 ptToSyRate);

}

File 24 of 31 : WrapperHelper.sol
// SPDX-License-Identifier: -- WISE --

pragma solidity =0.8.25;

import "../InterfaceHub/IWETH.sol";

contract WrapperHelper {

    IWETH internal immutable WETH;

    constructor(
        address _wethAddress
    )
    {
        WETH = IWETH(
            _wethAddress
        );
    }

    /**
     * @dev Wrapper for wrapping
     * ETH call.
     */
    function _wrapETH(
        uint256 _value
    )
        internal
    {
        WETH.deposit{
            value: _value
        }();
    }

    /**
     * @dev Wrapper for unwrapping
     * ETH call.
     */
    function _unwrapETH(
        uint256 _value
    )
        internal
    {
        WETH.withdraw(
            _value
        );
    }
}

File 25 of 31 : TransferHelper.sol
// SPDX-License-Identifier: -- WISE --

pragma solidity =0.8.25;

import "./CallOptionalReturn.sol";

contract TransferHelper is CallOptionalReturn {

    /**
     * @dev
     * Allows to execute safe transfer for a token
     */
    function _safeTransfer(
        address _token,
        address _to,
        uint256 _value
    )
        internal
    {
        _callOptionalReturn(
            _token,
            abi.encodeWithSelector(
                IERC20.transfer.selector,
                _to,
                _value
            )
        );
    }

    /**
     * @dev
     * Allows to execute safe transferFrom for a token
     */
    function _safeTransferFrom(
        address _token,
        address _from,
        address _to,
        uint256 _value
    )
        internal
    {
        _callOptionalReturn(
            _token,
            abi.encodeWithSelector(
                IERC20.transferFrom.selector,
                _from,
                _to,
                _value
            )
        );
    }
}

File 26 of 31 : ApprovalHelper.sol
// SPDX-License-Identifier: -- WISE --

pragma solidity =0.8.25;

import "./CallOptionalReturn.sol";

contract ApprovalHelper is CallOptionalReturn {

    /**
     * @dev
     * Allows to execute safe approve for a token
     */
    function _safeApprove(
        address _token,
        address _spender,
        uint256 _value
    )
        internal
    {
        if (_spender == address(0)) {
            return;
        }

        _callOptionalReturn(
            _token,
            abi.encodeWithSelector(
                IERC20.approve.selector,
                _spender,
                _value
            )
        );
    }
}

File 27 of 31 : SendValueHelper.sol
// SPDX-License-Identifier: -- WISE --

pragma solidity =0.8.25;

error AmountTooSmall();
error SendValueFailed();

contract SendValueHelper {

    bool public sendingProgress;

    function _sendValue(
        address _recipient,
        uint256 _amount
    )
        internal
    {
        if (address(this).balance < _amount) {
            revert AmountTooSmall();
        }

        sendingProgress = true;

        (
            bool success
            ,
        ) = payable(_recipient).call{
            value: _amount
        }("");

        sendingProgress = false;

        if (success == false) {
            revert SendValueFailed();
        }
    }
}

File 28 of 31 : GenericErrors.sol
// SPDX-License-Identifier: -- WISE --

pragma solidity =0.8.25;

error GenericDeactivated();
error GenericAccessDenied();
error GenericInvalidParam();
error GenericTooManyShares();
error GenericAmountTooSmall();
error GenericLevergeTooHigh();
error GenericDebtRatioTooLow();
error GenericNotBalancerVaultOrSelf();
error GenericDebtRatioTooHigh();
error GenericSendingOnGoing();

error GenericWrongExtRouter(
    address _unverifiedExtRouter
);
error GenericWrongPendleSwap(
    address _unverifiedPendleSwap
);
error GenericWrongLimitRouter(
    address _unverifiedLimitRouter
);
error GenericWrongMarket(
    address _unverifiedMarket,
    address _expectedMarket
);
error GenericWrongTokenIn(
    address _unverifiedTokenIn,
    address _expectedTokenIn
);
error GenericWrongTokenOut(
    address _unverifiedTokenOut,
    address _expectedTokenOut
);
error GenericWrongReceiver(
    address _unverifiedReceiver,
    address _expectedReceiver
);
error GenericInvalidSelector(
    bytes4 _unverifiedSelector,
    bytes4 _expectedSelector
);
error GenericRoutingOngoing();
error GenericNotV2Pair(
    address,
    address
);
error GenericNotV3Pair(
    address,
    address
);
error GenericNotSender();
error BadDebt(
    uint256 amount
);

File 29 of 31 : IERC20.sol
// SPDX-License-Identifier: -- WISE --

pragma solidity =0.8.25;

interface IERC20 {

    function totalSupply()
        external
        view
        returns (uint256);

    function balanceOf(
        address _account
    )
        external
        view
        returns (uint256);

    function transferFrom(
        address _sender,
        address _recipient,
        uint256 _amount
    )
        external
        returns (bool);

    function transfer(
        address _recipient,
        uint256 _amount
    )
        external
        returns (bool);

    function allowance(
        address owner,
        address spender
    )
        external
        view
        returns (uint256);

    function approve(
        address _spender,
        uint256 _amount
    )
        external
        returns (bool);

    function decimals()
        external
        view
        returns (uint8);

    event Transfer(
        address indexed from,
        address indexed to,
        uint256 value
    );

    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 value
    );

    event  Deposit(
        address indexed dst,
        uint wad
    );

    event  Withdrawal(
        address indexed src,
        uint wad
    );
}

File 30 of 31 : IWETH.sol
// SPDX-License-Identifier: -- WISE --

pragma solidity =0.8.25;

import "./IERC20.sol";

interface IWETH is IERC20 {

    function deposit()
        external
        payable;

    function withdraw(
        uint256
    )
        external;
}

File 31 of 31 : CallOptionalReturn.sol
// SPDX-License-Identifier: -- WISE --

pragma solidity =0.8.25;

import "../InterfaceHub/IERC20.sol";

contract CallOptionalReturn {

    /**
     * @dev Helper function to do low-level call
     */
    function _callOptionalReturn(
        address token,
        bytes memory data
    )
        internal
        returns (bool call)
    {
        (
            bool success,
            bytes memory returndata
        ) = token.call(
            data
        );

        bool results = returndata.length == 0 || abi.decode(
            returndata,
            (bool)
        );

        if (success == false) {
            revert();
        }

        call = success
            && results
            && token.code.length > 0;
    }
}

Settings
{
  "remappings": [
    "@pythnetwork/pyth-sdk-solidity/=node_modules/@pythnetwork/pyth-sdk-solidity/",
    "@chainlink/contracts/=node_modules/@chainlink/contracts/",
    "@balancer-labs/=node_modules/@balancer-labs/",
    "@ensdomains/=node_modules/@ensdomains/",
    "@eth-optimism/=node_modules/@eth-optimism/",
    "@openzeppelin/=node_modules/@openzeppelin/",
    "@pendle/=node_modules/@pendle/",
    "@scroll-tech/=node_modules/@scroll-tech/",
    "@uniswap/=node_modules/@uniswap/",
    "base64-sol/=node_modules/base64-sol/",
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "eth-gas-reporter/=node_modules/eth-gas-reporter/",
    "forge-std/=lib/forge-std/src/",
    "hardhat/=node_modules/hardhat/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 20
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "cancun",
  "viaIR": false,
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_wiseLendingAddress","type":"address"},{"internalType":"address","name":"_pendleChildTokenAddress","type":"address"},{"internalType":"address","name":"_pendleRouter","type":"address"},{"internalType":"address","name":"_entryAsset","type":"address"},{"internalType":"address","name":"_pendleSy","type":"address"},{"internalType":"address","name":"_underlyingMarket","type":"address"},{"internalType":"address","name":"_routerStatic","type":"address"},{"internalType":"address","name":"_dexAddress","type":"address"},{"internalType":"uint256","name":"_collateralFactor","type":"uint256"},{"internalType":"address","name":"_powerFarmNFTs","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyReserved","type":"error"},{"inputs":[],"name":"AmountTooSmall","type":"error"},{"inputs":[],"name":"ApiRoutingCallFailed","type":"error"},{"inputs":[],"name":"ApiRoutingDebtRatioTooHigh","type":"error"},{"inputs":[],"name":"ApiRoutingTooMuchValueLost","type":"error"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"BadDebt","type":"error"},{"inputs":[],"name":"GenericAccessDenied","type":"error"},{"inputs":[],"name":"GenericAmountTooSmall","type":"error"},{"inputs":[],"name":"GenericDeactivated","type":"error"},{"inputs":[],"name":"GenericDebtRatioTooHigh","type":"error"},{"inputs":[],"name":"GenericDebtRatioTooLow","type":"error"},{"inputs":[],"name":"GenericInvalidParam","type":"error"},{"inputs":[{"internalType":"bytes4","name":"_unverifiedSelector","type":"bytes4"},{"internalType":"bytes4","name":"_expectedSelector","type":"bytes4"}],"name":"GenericInvalidSelector","type":"error"},{"inputs":[],"name":"GenericLevergeTooHigh","type":"error"},{"inputs":[],"name":"GenericNotBalancerVaultOrSelf","type":"error"},{"inputs":[],"name":"GenericNotSender","type":"error"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"GenericNotV2Pair","type":"error"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"GenericNotV3Pair","type":"error"},{"inputs":[],"name":"GenericRoutingOngoing","type":"error"},{"inputs":[],"name":"GenericSendingOnGoing","type":"error"},{"inputs":[],"name":"GenericTooManyShares","type":"error"},{"inputs":[{"internalType":"address","name":"_unverifiedExtRouter","type":"address"}],"name":"GenericWrongExtRouter","type":"error"},{"inputs":[{"internalType":"address","name":"_unverifiedLimitRouter","type":"address"}],"name":"GenericWrongLimitRouter","type":"error"},{"inputs":[{"internalType":"address","name":"_unverifiedMarket","type":"address"},{"internalType":"address","name":"_expectedMarket","type":"address"}],"name":"GenericWrongMarket","type":"error"},{"inputs":[{"internalType":"address","name":"_unverifiedPendleSwap","type":"address"}],"name":"GenericWrongPendleSwap","type":"error"},{"inputs":[{"internalType":"address","name":"_unverifiedReceiver","type":"address"},{"internalType":"address","name":"_expectedReceiver","type":"address"}],"name":"GenericWrongReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"_unverifiedTokenIn","type":"address"},{"internalType":"address","name":"_expectedTokenIn","type":"address"}],"name":"GenericWrongTokenIn","type":"error"},{"inputs":[{"internalType":"address","name":"_unverifiedTokenOut","type":"address"},{"internalType":"address","name":"_expectedTokenOut","type":"address"}],"name":"GenericWrongTokenOut","type":"error"},{"inputs":[],"name":"InvalidKey","type":"error"},{"inputs":[],"name":"NoValue","type":"error"},{"inputs":[],"name":"NotMaster","type":"error"},{"inputs":[],"name":"NotProposed","type":"error"},{"inputs":[],"name":"SendValueFailed","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"_data","type":"bytes"}],"name":"ERC721Received","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"from","type":"address"}],"name":"ETHReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"keyId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"wiseLendingNFT","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"leverage","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountAfterMintFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"FarmEntry","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"keyId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"wiseLendingNFT","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"FarmExit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bool","name":"state","type":"bool"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"FarmStatus","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"keyId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"wiseLendingNFT","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"ManualPaybackShares","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"keyId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"wiseLendingNFT","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"ManualWithdrawShares","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"proposer","type":"address"},{"indexed":true,"internalType":"address","name":"proposedMaster","type":"address"}],"name":"MasterProposed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"minDepositEthAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"MinDepositChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"nftId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"RegistrationFarm","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousMaster","type":"address"}],"name":"RenouncedOwnership","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_contract","type":"address"},{"indexed":false,"internalType":"bool","name":"_isWhiteListed","type":"bool"}],"name":"WhiteListedExternalContract","type":"event"},{"inputs":[],"name":"AAVE","outputs":[{"internalType":"contract IAave","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"AAVE_HUB","outputs":[{"internalType":"contract IAaveHub","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"AAVE_NATIVE_USDC_ARBITRUM_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"AAVE_USDC_ADDRESS_ETH_MAIN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BALANCER_VAULT","outputs":[{"internalType":"contract IBalancerVault","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ENTRY_ASSET","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FARM_ASSET","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NATIVE_USDC_ARBITRUM_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ORACLE_HUB","outputs":[{"internalType":"contract IWiseOracleHub","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PENDLE_CHILD","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PENDLE_LIMIT_ROUTER_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PENDLE_MARKET","outputs":[{"internalType":"contract IPendleMarket","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PENDLE_ROUTER","outputs":[{"internalType":"contract IPendleRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PENDLE_ROUTER_STATIC","outputs":[{"internalType":"contract IPendleRouterStatic","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PENDLE_SY","outputs":[{"internalType":"contract IPendleSy","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"POOL_ASSET_AAVE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"POSITION_NFT","outputs":[{"internalType":"contract IPositionNFTs","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PT_ORACLE_PENDLE","outputs":[{"internalType":"contract IOraclePendle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNISWAP_FACTORY","outputs":[{"internalType":"contract IUniswapFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNISWAP_FACTORY_V2_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNISWAP_V2_POOL","outputs":[{"internalType":"contract IUniswapV2Pool","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNISWAP_V3_FEE","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNISWAP_V3_POOL","outputs":[{"internalType":"contract IUniswapV3PoolPowerFarm","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNISWAP_V3_ROUTER","outputs":[{"internalType":"contract IUniswapV3","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"USDC_ETH_MAIN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WISE_LENDING","outputs":[{"internalType":"contract IWiseLending","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WISE_SECURITY","outputs":[{"internalType":"contract IWiseSecurity","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountWithdrawn","type":"uint256"}],"name":"_calculateFlashLoanFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"allowEnter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"availableNFTCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"availableNFTs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newMinDeposit","type":"uint256"}],"name":"changeMinDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newPendleRouter","type":"address"},{"internalType":"address","name":"_newLimitRouter","type":"address"}],"name":"changePendleRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newUniV3Pool","type":"address"}],"name":"changeUniV3Pool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"collateralFactor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collateralFactorRole","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"doApprovals","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_callData","type":"bytes"},{"internalType":"bool","name":"_isAave","type":"bool"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_leverage","type":"uint256"},{"internalType":"uint256","name":"_allowedSpread","type":"uint256"}],"name":"enterFarm","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_callData","type":"bytes"},{"internalType":"bool","name":"_isAave","type":"bool"},{"internalType":"uint256","name":"_leverage","type":"uint256"},{"internalType":"uint256","name":"_allowedSpread","type":"uint256"}],"name":"enterFarmETH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"ethBack","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_callData","type":"bytes"},{"internalType":"uint256","name":"_keyId","type":"uint256"},{"internalType":"uint256","name":"_allowedSpread","type":"uint256"},{"internalType":"bool","name":"_ethBack","type":"bool"}],"name":"exitFarm","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"farmData","outputs":[{"internalType":"uint256","name":"wiseLendingNFT","type":"uint256"},{"internalType":"uint256","name":"leverage","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"amountAfterMintFee","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"farmingKeys","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_initialAmount","type":"uint256"},{"internalType":"uint256","name":"_leverage","type":"uint256"},{"internalType":"uint256","name":"_pendleChildApy","type":"uint256"},{"internalType":"bool","name":"_isAave","type":"bool"}],"name":"getApproxNetAPY","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_initialAmount","type":"uint256"},{"internalType":"uint256","name":"_leverage","type":"uint256"}],"name":"getLeverageAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nftId","type":"uint256"}],"name":"getLiveDebtRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_borrowAmount","type":"uint256"},{"internalType":"bool","name":"_isAave","type":"bool"}],"name":"getNewBorrowRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nftId","type":"uint256"}],"name":"getPositionBorrowETH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nftId","type":"uint256"}],"name":"getTokenAmountEquivalentInFarmAsset","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nftId","type":"uint256"}],"name":"getTotalWeightedCollateralETH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"isAave","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_keyId","type":"uint256"},{"internalType":"address","name":"_owner","type":"address"}],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isShutdown","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nftId","type":"uint256"},{"internalType":"uint256","name":"_nftIdLiquidator","type":"uint256"},{"internalType":"uint256","name":"_shareAmountToPay","type":"uint256"}],"name":"liquidatePartiallyFromToken","outputs":[{"internalType":"uint256","name":"paybackAmount","type":"uint256"},{"internalType":"uint256","name":"receivingAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_keyId","type":"uint256"},{"internalType":"uint256","name":"_paybackShares","type":"uint256"}],"name":"manuallyPaybackShares","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_keyId","type":"uint256"},{"internalType":"uint256","name":"_withdrawShares","type":"uint256"}],"name":"manuallyWithdrawShares","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"master","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minDepositEthAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintReserved","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"},{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_proposedOwner","type":"address"}],"name":"proposeOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"proposedMaster","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20[]","name":"_flashloanToken","type":"address[]"},{"internalType":"uint256[]","name":"_flashloanAmounts","type":"uint256[]"},{"internalType":"uint256[]","name":"_feeAmounts","type":"uint256[]"},{"internalType":"bytes","name":"_userData","type":"bytes"}],"name":"receiveFlashLoan","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"reservedKeys","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"revokeCollateralFactorRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"routingOngoing","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sendingProgress","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newCollateralFactor","type":"uint256"}],"name":"setCollateralFactor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_state","type":"bool"}],"name":"setSpecialDepegCase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_whiteList","type":"address[]"},{"internalType":"bool[]","name":"_isWhiteListed","type":"bool[]"}],"name":"setWhiteListForContracts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_state","type":"bool"}],"name":"shutDownFarm","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"specialDepegCase","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalReserved","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"uniswapV2Call","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fee0","type":"uint256"},{"internalType":"uint256","name":"_fee1","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"uniswapV3FlashCallback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whiteListedExternalContracts","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

610320604052606461001a670de0b6b3a76400006060610965565b610024919061098e565b600455601680546001600160a01b0319908116734e0924d3a751be199c426d52fb1f2337fa96f73617909155601780549091167398c23e9d8f34fefb1b7bd6a91b7ff122f4e16f5c17905534801561007a575f80fd5b50604051616b35380380616b35833981016040819052610099916109c8565b89898989898989898989466001146100c55773af88d065e77c8cc2239327c5edb3a432268e58316100db565b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb485b466001146100fd5773724dc807b04555b71ed48a6896b6f41593b8c63761010a565b6017546001600160a01b03165b8b8b8b8b8b8b8b8b8b8b808a8a8a8a8a8a8a8a8a886001600160a01b031663040141e56040518163ffffffff1660e01b8152600401602060405180830381865afa15801561015a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061017e9190610a75565b338061019d5760405163f2365b5b60e01b815260040160405180910390fd5b5f80546001600160a01b03199081166001600160a01b0393841617909155918116608052848116610240528581166102205286811661020052600a80549092168982161790915582166101c052465f190161020c57735c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f6101e0525b6001600160a01b0380871660a05288811660c052891661012081905260408051637cc97da560e01b81529051637cc97da5916004808201926020929091908290030181865afa158015610261573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102859190610a75565b6001600160a01b039081166101405273ba12222222228d8ba445958a75a0704d566bf2c8610180526101205160408051630f9f234d60e01b815290519190921691630f9f234d9160048083019260209291908290030181865afa1580156102ee573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103129190610a75565b6001600160a01b0316610160816001600160a01b031681525050610120516001600160a01b031663040141e56040518163ffffffff1660e01b8152600401602060405180830381865afa15801561036b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061038f9190610a75565b6001600160a01b0316610280816001600160a01b031681525050610160516001600160a01b031663730e695d6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103e8573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061040c9190610a75565b6001600160a01b03166101008190526040805163205d6b8760e21b81529051638175ae1c916004808201926020929091908290030181865afa158015610454573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104789190610a75565b6001600160a01b039081166102a081905260e0526101005181166102c0526101205160408051637c854ec760e01b815290519190921691637c854ec79160048083019260209291908290030181865afa1580156104d7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104fb9190610a75565b6001600160a01b03166101a0816001600160a01b03168152505080600281905550610100516001600160a01b0316634d8e4597610100516001600160a01b031663040141e56040518163ffffffff1660e01b8152600401602060405180830381865afa15801561056d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105919190610a75565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa1580156105d3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105f79190610a75565b6001600160a01b03166102e052731fd95db7b7c0067de8d45c0cb35d59796adfd18761026052600780546001600160a01b0319166dc9b3e2c3ec88b1b4c0cd853f4321179055666a94d74f4300006003555f194601610676576729a2241af62c00006003557366a1096c6366b2529274df4f5d8247827fe4cea8610260525b505050505050505050806001600160a01b0316610300816001600160a01b03168152505050505050505050505050508160055f6101000a8154816001600160a01b0302191690836001600160a01b031602179055508060065f6101000a8154816001600160a01b0302191690836001600160a01b031602179055506107008c61075860201b60201c565b600b80546001600160a01b031916331790554660010361073d57601654600980546001600160a01b0319166001600160a01b039092169190911790555b50505050505050505050505050505050505050505050610aca565b600654610770906001600160a01b0316825f19610841565b60055460075461078e916001600160a01b0390811691165f19610841565b610220516007546107aa91906001600160a01b03165f19610841565b61022051600a546107c691906001600160a01b03165f19610841565b6005546107de906001600160a01b0316825f19610841565b60c0516107ed90825f19610841565b6108046102205160c0515f1961084160201b60201c565b60055461010051610820916001600160a01b0316905f19610841565b600554600a5461083e916001600160a01b0390811691165f19610841565b50565b6001600160a01b03821661085457505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091526108aa9185916108b016565b50505050565b5f805f846001600160a01b0316846040516108cb9190610a95565b5f604051808303815f865af19150503d805f8114610904576040519150601f19603f3d011682016040523d82523d5f602084013e610909565b606091505b50915091505f81515f148061092d57508180602001905181019061092d9190610aab565b90508215155f0361093c575f80fd5b8280156109465750805b801561095b57505f866001600160a01b03163b115b9695505050505050565b808202811582820484141761098857634e487b7160e01b5f52601160045260245ffd5b92915050565b5f826109a857634e487b7160e01b5f52601260045260245ffd5b500490565b80516001600160a01b03811681146109c3575f80fd5b919050565b5f805f805f805f805f806101408b8d0312156109e2575f80fd5b6109eb8b6109ad565b99506109f960208c016109ad565b9850610a0760408c016109ad565b9750610a1560608c016109ad565b9650610a2360808c016109ad565b9550610a3160a08c016109ad565b9450610a3f60c08c016109ad565b9350610a4d60e08c016109ad565b92506101008b01519150610a646101208c016109ad565b90509295989b9194979a5092959850565b5f60208284031215610a85575f80fd5b610a8e826109ad565b9392505050565b5f82518060208501845e5f920191825250919050565b5f60208284031215610abb575f80fd5b81518015158114610a8e575f80fd5b60805160a05160c05160e05161010051610120516101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516102e05161030051615de9610d4c5f395f818161174a01528181611af1015261328b01525f50505f6129bd01525f50505f81816103ee015261452601525f610b9b01525f6109c901525f8181610563015281816121d20152818161220b01528181612284015281816149f50152614a2f01525f610d2201525f8181610e04015261116201525f61078f01525f8181610ab6015281816128ef015261299001525f8181610d550152613b0001525f61059601525f8181610b34015281816120f1015261280901525f8181610c73015281816115280152818161191201528181612384015281816124e00152818161255e015281816125d8015281816126a80152818161274301528181612d2401528181612db2015281816130520152818161310f015281816131a301528181613452015281816134c2015281816135480152818161377a01528181613bce01528181613c9f01528181613e0e01528181614398015261444a01525f8181610a10015281816122dd015281816124260152818161430401526143f601525f6107e101525f81816104ea0152818161142301528181611644015281816120ab01528181612258015281816122a50152818161260701528181612af301528181612b2001528181612b4c0152818161301c0152818161348101528181613d1f01528181613d9b01528181613e3d01528181613f5301528181613f7401528181613fa601528181613fd00152818161448701526144ba01525f8181610471015261413901525f6128710152615de95ff3fe6080604052600436106103a6575f3560e01c806376c4b7db116101e7578063ba1ad31011610107578063ba1ad31014610cf2578063bb62efbc14610d11578063bc16384614610d44578063bf86d69014610d77578063c157301814610d97578063c27d98fc14610dbf578063c71b0e1c14610dde578063c74c0fac14610df3578063c7aebf5114610e26578063ca3a341a14610e3b578063d18f838f14610e5a578063d3573a3314610eca578063d4f7d90914610ee9578063df011c4114610f09578063e9b2e0d714610f1e578063e9cbafb014610f49578063ec8c890414610f68578063ee97f7f314610f7c578063f04f270714610f9a578063fd41c1d814610fb9575f80fd5b806376c4b7db14610a3257806377314b3714610a47578063798501a914610a665780637a19daea14610a855780637c854ec714610aa557806385dfb48914610ad85780639532ba8514610b035780639751a63f14610b235780639a8a8c5314610b565780639ef2e82d14610b8a5780639f29e7e014610bbd5780639f6cb4dd14610bdc578063a1c44ae014610bfb578063a2309ff814610c1a578063a799566c14610c2f578063a96bb61114610c43578063b56453e414610c62578063b5c2215714610c95578063b5ed298a14610cb4578063b750ee6814610cd3575f80fd5b806341c64a2f116102d257806341c64a2f1461077e57806344b6b11c146107b157806348ccda3c146107d05780634b2a12da146108035780634cacc937146108225780634e71e0c8146108415780634f3823d114610855578063525fbf211461087457806359adab9e146108935780635a5d096c146108a65780635aa6d763146108c55780635ba6b948146108e45780635cb36970146109035780635d4f7742146109375780636016f12d1461094b5780636195af6a1461096b578063627ba5c51461099957806364a1e64b146109b8578063715018a6146109eb578063730e695d146109ff575f80fd5b80623cbb3214610460578063019dbb63146104a957806302eb092a146104d95780630764b9af1461050c5780630dc192da1461052b5780630f61ac82146105525780630f9f234d1461058557806310d1e85c146105b8578063148af2c5146105d7578063150b7a02146105fe5780631b4ff3c3146106365780631bb288e71461065d5780631e183b7a1461068a57806326f4e37d146106a957806327a4986b146106c85780632c5ebc83146106f357806331418fb61461071257806338271bf6146107315780633c97b00d1461075f575f80fd5b3661045c577f49109bdae8e3bbdcbeb7fe5b25b1c75a6bc84fd3f27c6ee0633d41fe197f2aba34336040516103dc929190614bde565b60405180910390a16001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016330361041657005b60018054600160a01b900460ff161515900361044557604051631976c42360e01b815260040160405180910390fd5b5f5461045a906001600160a01b031634610fe0565b005b5f80fd5b34801561046b575f80fd5b506104937f000000000000000000000000000000000000000000000000000000000000000081565b6040516104a09190614bf5565b60405180910390f35b3480156104b4575f80fd5b506001546104c990600160a01b900460ff1681565b60405190151581526020016104a0565b3480156104e4575f80fd5b506104937f000000000000000000000000000000000000000000000000000000000000000081565b348015610517575f80fd5b50600754610493906001600160a01b031681565b348015610536575f80fd5b50610493735c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f81565b34801561055d575f80fd5b506104937f000000000000000000000000000000000000000000000000000000000000000081565b348015610590575f80fd5b506104937f000000000000000000000000000000000000000000000000000000000000000081565b3480156105c3575f80fd5b5061045a6105d2366004614c61565b611099565b3480156105e2575f80fd5b5061049373a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b348015610609575f80fd5b5061061d610618366004614cc5565b6113bf565b6040516001600160e01b031990911681526020016104a0565b348015610641575f80fd5b5061049373af88d065e77c8cc2239327c5edb3a432268e583181565b348015610668575f80fd5b5061067c610677366004614d15565b611411565b6040519081526020016104a0565b348015610695575f80fd5b5061045a6106a4366004614d39565b61146a565b3480156106b4575f80fd5b5061045a6106c3366004614d39565b611490565b3480156106d3575f80fd5b5061067c6106e2366004614d15565b60136020525f908152604090205481565b3480156106fe575f80fd5b50600554610493906001600160a01b031681565b34801561071d575f80fd5b5061045a61072c366004614d54565b6114eb565b34801561073c575f80fd5b506104c961074b366004614d8b565b600e6020525f908152604090205460ff1681565b34801561076a575f80fd5b50600a54610493906001600160a01b031681565b348015610789575f80fd5b506104937f000000000000000000000000000000000000000000000000000000000000000081565b3480156107bc575f80fd5b50600954610493906001600160a01b031681565b3480156107db575f80fd5b506104937f000000000000000000000000000000000000000000000000000000000000000081565b34801561080e575f80fd5b5061045a61081d366004614d15565b611550565b34801561082d575f80fd5b5061045a61083c366004614da6565b611599565b34801561084c575f80fd5b5061045a611622565b348015610860575f80fd5b50600654610493906001600160a01b031681565b34801561087f575f80fd5b5061067c61088e366004614d15565b61163d565b61067c6108a1366004614f11565b6116cf565b3480156108b1575f80fd5b506104c96108c0366004614f6b565b611717565b3480156108d0575f80fd5b5061067c6108df366004614f8e565b6117f3565b3480156108ef575f80fd5b5061045a6108fe366004614da6565b61184b565b34801561090e575f80fd5b5061092261091d366004614ff2565b6118f1565b604080519283529015156020830152016104a0565b348015610942575f80fd5b5061045a61190d565b348015610956575f80fd5b506001546104c990600160b01b900460ff1681565b348015610976575f80fd5b506104c9610985366004614d15565b600d6020525f908152604090205460ff1681565b3480156109a4575f80fd5b5061045a6109b33660046150c2565b611938565b3480156109c3575f80fd5b506104937f000000000000000000000000000000000000000000000000000000000000000081565b3480156109f6575f80fd5b5061045a611a30565b348015610a0a575f80fd5b506104937f000000000000000000000000000000000000000000000000000000000000000081565b348015610a3d575f80fd5b5061067c60125481565b348015610a52575f80fd5b5061045a610a6136600461517d565b611a7c565b348015610a71575f80fd5b5061067c610a803660046151d0565b611be0565b348015610a90575f80fd5b50600b546104c990600160b01b900460ff1681565b348015610ab0575f80fd5b506104937f000000000000000000000000000000000000000000000000000000000000000081565b348015610ae3575f80fd5b5061067c610af2366004614d8b565b60146020525f908152604090205481565b348015610b0e575f80fd5b50600b546104c990600160a81b900460ff1681565b348015610b2e575f80fd5b506104937f000000000000000000000000000000000000000000000000000000000000000081565b348015610b61575f80fd5b50610b75610b703660046151f3565b611bf2565b604080519283526020830191909152016104a0565b348015610b95575f80fd5b506104937f000000000000000000000000000000000000000000000000000000000000000081565b348015610bc8575f80fd5b50600b54610493906001600160a01b031681565b348015610be7575f80fd5b5061045a610bf6366004614d8b565b611c23565b348015610c06575f80fd5b5061067c610c15366004614da6565b611c4d565b348015610c25575f80fd5b5061067c60105481565b348015610c3a575f80fd5b5061045a611c6b565b348015610c4e575f80fd5b5061067c610c5d366004614d15565b611c85565b348015610c6d575f80fd5b506104937f000000000000000000000000000000000000000000000000000000000000000081565b348015610ca0575f80fd5b5061045a610caf366004614d15565b611d07565b348015610cbf575f80fd5b5061045a610cce366004614d8b565b611d14565b348015610cde575f80fd5b5061067c610ced366004614d15565b611d8e565b348015610cfd575f80fd5b50601754610493906001600160a01b031681565b348015610d1c575f80fd5b506104937f000000000000000000000000000000000000000000000000000000000000000081565b348015610d4f575f80fd5b506104937f000000000000000000000000000000000000000000000000000000000000000081565b348015610d82575f80fd5b506001546104c990600160a81b900460ff1681565b348015610da2575f80fd5b50610dab606481565b60405162ffffff90911681526020016104a0565b348015610dca575f80fd5b50600854610493906001600160a01b031681565b348015610de9575f80fd5b5061067c60115481565b348015610dfe575f80fd5b506104937f000000000000000000000000000000000000000000000000000000000000000081565b348015610e31575f80fd5b5061067c60035481565b348015610e46575f80fd5b5061067c610e55366004614d15565b611dbe565b348015610e65575f80fd5b50610ea2610e74366004614d15565b600c6020525f9081526040902080546001820154600283015460038401546004909401549293919290919085565b604080519586526020860194909452928401919091526060830152608082015260a0016104a0565b348015610ed5575f80fd5b50600154610493906001600160a01b031681565b348015610ef4575f80fd5b50600b546104c990600160a01b900460ff1681565b348015610f14575f80fd5b5061067c60025481565b348015610f29575f80fd5b5061067c610f38366004614d15565b60156020525f908152604090205481565b348015610f54575f80fd5b5061045a610f6336600461521c565b611e5e565b348015610f73575f80fd5b5061067c612013565b348015610f87575f80fd5b505f54610493906001600160a01b031681565b348015610fa5575f80fd5b5061045a610fb43660046152c6565b612033565b348015610fc4575f80fd5b5061049373724dc807b04555b71ed48a6896b6f41593b8c63781565b804710156110015760405163617ab12d60e11b815260040160405180910390fd5b6001805460ff60a01b1916600160a01b1790556040515f906001600160a01b0384169083908381818185875af1925050503d805f811461105c576040519150601f19603f3d011682016040523d82523d5f602084013e611061565b606091505b50506001805460ff60a01b1916905590508015155f036110945760405163120086e360e11b815260040160405180910390fd5b505050565b5f336001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110d6573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110fa91906153d7565b90505f336001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611139573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061115d91906153d7565b90505f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e6a4390584846040518363ffffffff1660e01b81526004016111ae9291906153f2565b602060405180830381865afa1580156111c9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111ed91906153d7565b6008549091506001600160a01b0316331461122857338160405163d36d48d360e01b815260040161121f9291906153f2565b60405180910390fd5b6001600160a01b03881630146112515760405163d949d27360e01b815260040160405180910390fd5b6040805160018082528183019092525f9160208083019080368337505060055482519293506001600160a01b0316918391505f906112915761129161540c565b6001600160a01b0392909216602092830291909101909101526040805160018082528183019092525f9181602001602082028036833701905050905088156112d957886112db565b875b815f815181106112ed576112ed61540c565b60209081029190910101526040805160018082528183019092525f9181602001602082028036833701905050905061133d825f815181106113305761133061540c565b6020026020010151611d8e565b815f8151811061134f5761134f61540c565b602090810291909101015260405163f04f270760e01b8152309063f04f270790611385908690869086908e908e906004016154ba565b5f604051808303815f87803b15801561139c575f80fd5b505af11580156113ae573d5f803e3d5ffd5b505050505050505050505050505050565b5f7fa05d90f300156ad1b545bc5d8197024456f21d22a708f5af04dd293e3d60525186868686866040516113f7959493929190615507565b60405180910390a150630a85bd0160e11b95945050505050565b5f670de0b6b3a76400006002546114507f000000000000000000000000000000000000000000000000000000000000000061144b866120a5565b6120d8565b61145a919061554e565b6114649190615565565b92915050565b611472612167565b600b8054911515600160a81b0260ff60a81b19909216919091179055565b611498612167565b6001805460ff60a81b1916600160a81b831515908102919091179091556040514281527fb9c62307336e3148a6afd10d350797a6544eb07ddfb98cf05f49a4cd55d863639060200160405180910390a250565b6114f3612167565b600a80546001600160a01b038085166001600160a01b031992831617909255600780549284169290911691909117905561154c7f0000000000000000000000000000000000000000000000000000000000000000612193565b5050565b611558612167565b6003819055604080518281524260208201527f6d41ef415406b2fbd2e8e6c2fa40f471038209962c13e3e9280a9bdf3219983c91015b60405180910390a150565b6115a1612324565b6115a9612353565b6115b16124c6565b5f828152601360205260409020546115c99082612658565b60135f8381526020019081526020015f2054827fa30b3c2ccf1776c70e08f1e8f7d7eb571fe975803f15f61c7526e7947d7504ff8342604051611616929190918252602082015260400190565b60405180910390a35050565b61162a6127c3565b5f80546001600160a01b03191633179055565b5f8061166c7f000000000000000000000000000000000000000000000000000000000000000061144b856120a5565b90505f61167884611dbe565b9050808210156116a85761168c8282615584565b604051631309868760e11b815260040161121f91815260200190565b6005546116c7906001600160a01b03166116c28385615584565b6127f0565b949350505050565b5f6116d8612324565b6116e0612840565b6116e8612353565b6116f06124c6565b6116f93461286f565b61170e85856117066128e2565b348787612a45565b95945050505050565b6001600160a01b0381165f9081526014602052604081205483900361173e57506001611464565b816001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316636352211e856040518263ffffffff1660e01b815260040161179691815260200190565b602060405180830381865afa1580156117b1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117d591906153d7565b6001600160a01b0316036117eb57506001611464565b505f92915050565b5f6117fc612324565b611804612840565b61180c612353565b6118146124c6565b60055461182c906001600160a01b0316333087612a6b565b61184186866118396128e2565b878787612a45565b9695505050505050565b611853612324565b61185b612353565b6118636124c6565b8161186d81612ad6565b5f838152601360205260409020546118858184612aed565b61188e81612b72565b15155f036118af57604051632595e55760e21b815260040160405180910390fd5b60408051848152426020820152829186917f54f4c57f40abbe4603bbaf72e5e1d421b094a958865111157f36f674a40cd69a910160405180910390a350505050565b5f806118ff86868686612bcd565b915091505b94509492505050565b6119367f0000000000000000000000000000000000000000000000000000000000000000612193565b565b611940612167565b5f5b8251811015611094576119b1600e8483815181106119625761196261540c565b602002602001015184848151811061197c5761197c61540c565b60200260200101516001600160a01b039091165f9081526020929092526040909120805491151560ff19909216919091179055565b8281815181106119c3576119c361540c565b60200260200101516001600160a01b03167f2f48f3e37e626249e017c7289e8781a491500cbad4dc44fa692573419b5acedd838381518110611a0757611a0761540c565b6020026020010151604051611a20911515815260200190565b60405180910390a2600101611942565b611a38612167565b5f80546001600160a01b0319908116825560018054909116905560405133917f6172baf984ea013d88b784409f46655b96ba7f2ff91bca1ac9bcd27b113e6eb091a2565b611a84612324565b611a8c612353565b611a946124c6565b82611a9e81612ad6565b5f848152601360209081526040808320805490849055338452601490925290912054859003611adb57335f90815260146020526040812055611b51565b6040516390901aa360e01b8152600481018690527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906390901aa3906024015f604051808303815f87803b158015611b3a575f80fd5b505af1158015611b4c573d5f803e3d5ffd5b505050505b8060155f60125f8154611b6390615597565b9182905550815260208082019290925260409081015f90812093909355838352600d909152902054611b9c90879060ff16838787612c93565b60408051858152426020820152829187917f79b2e2d00a00811102e4c45a3a4d9866abcbe9f9471572632098aab13aedb52a910160405180910390a3505050505050565b5f611beb8383612cf5565b9392505050565b5f80611bfc612324565b611c04612353565b611c0c6124c6565b611c17858585612ef6565b91509150935093915050565b611c2b612167565b600980546001600160a01b0319166001600160a01b0392909216919091179055565b5f670de0b6b3a7640000611c61838561554e565b611beb9190615565565b611c736130c8565b600b80546001600160a01b0319169055565b5f818152600d6020526040812054819060ff16611caa57611ca5836130f3565b611cb3565b611cb383613187565b9050805f03611cc457505f92915050565b5f611cce84611411565b9050805f03611ce057505f9392505050565b80670de0b6b3a7640000611cf386611dbe565b611cfd919061554e565b6116c79190615565565b611d0f6130c8565b600255565b611d1c612167565b6001600160a01b038116611d435760405163f2365b5b60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03831690811790915560405133907f322fd6444c59daffa82e4689b7685b6fafc6109a1eff8a6ca10c5a8e3206cda1905f90a350565b5f816103e5611d9f826103e861554e565b611da99190615565565b611db39190615584565b6114649060016155af565b5f805f611dca846130f3565b90508015611dde57611ddb846131dc565b91505b5f611de885613187565b90505f8115611dfd57611dfa8661320e565b90505b5f8315611e1d57600554611e1a906001600160a01b0316866120d8565b90505b815f03611e2e579695505050505050565b6006545f90611e46906001600160a01b0316846120d8565b9050611e5281836155af565b98975050505050505050565b6009546001600160a01b03163314611e9a5760095460405163f50e080b60e01b815261121f9133916001600160a01b03909116906004016153f2565b600154600160b01b900460ff1615155f03611ec85760405163075c82fd60e31b815260040160405180910390fd5b6040805160018082528183019092525f9160208083019080368337505060055482519293506001600160a01b0316918391505f90611f0857611f0861540c565b6001600160a01b0392909216602092830291909101909101526040805160018082528183019092525f91816020016020820280368337019050509050600f54815f81518110611f5957611f5961540c565b60209081029190910101526040805160018082528183019092525f918160200160208202803683370190505090508615611f935786611f95565b855b815f81518110611fa757611fa761540c565b602090810291909101015260405163f04f270760e01b8152309063f04f270790611fdd908690869086908b908b906004016154ba565b5f604051808303815f87803b158015611ff4575f80fd5b505af1158015612006573d5f803e3d5ffd5b5050505050505050505050565b335f81815260146020526040812054909161202e9190613240565b905090565b61203e845133613321565b61209f81845f815181106120545761205461540c565b6020026020010151845f8151811061206e5761206e61540c565b6020026020010151865f815181106120885761208861540c565b602002602001015161209a91906155af565b6133ca565b50505050565b5f6114647f00000000000000000000000000000000000000000000000000000000000000006120d384613439565b6134a9565b604051630e8f811d60e41b81525f906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063e8f811d09061212890869086906004016155c2565b602060405180830381865afa158015612143573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611beb91906155db565b5f546001600160a01b0316330361217a57565b604051635a7617f960e11b815260040160405180910390fd5b6006546121ab906001600160a01b0316825f196134f9565b6005546007546121c9916001600160a01b0390811691165f196134f9565b600754612202907f0000000000000000000000000000000000000000000000000000000000000000906001600160a01b03165f196134f9565b600a5461223b907f0000000000000000000000000000000000000000000000000000000000000000906001600160a01b03165f196134f9565b600554612253906001600160a01b0316825f196134f9565b61227f7f0000000000000000000000000000000000000000000000000000000000000000825f196134f9565b6122cb7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000005f196134f9565b600554612303906001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000005f196134f9565b600554600a54612321916001600160a01b0390811691165f196134f9565b50565b600b54600160b01b900460ff1615156001036119365760405163391c8dbd60e01b815260040160405180910390fd5b60018054600160a01b900460ff16151590036123825760405163075c82fd60e31b815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663019dbb636040518163ffffffff1660e01b8152600401602060405180830381865afa1580156123de573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061240291906155f2565b15156001036124245760405163075c82fd60e31b815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316631786ef6d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612480573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124a491906155f2565b15156001036119365760405163075c82fd60e31b815260040160405180910390fd5b600554604051631ff631c360e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811692633fec638692612519929190911690600401614bf5565b5f604051808303815f87803b158015612530575f80fd5b505af1158015612542573d5f803e3d5ffd5b5050600654604051631ff631c360e11b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169450633fec63869350612596921690600401614bf5565b5f604051808303815f87803b1580156125ad575f80fd5b505af11580156125bf573d5f803e3d5ffd5b5050604051631ff631c360e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169250633fec6386915061262f907f000000000000000000000000000000000000000000000000000000000000000090600401614bf5565b5f604051808303815f87803b158015612646575f80fd5b505af115801561209f573d5f803e3d5ffd5b6005545f838152600d60205260409020546001600160a01b039091169060ff16151560010361268f57506006546001600160a01b03165b6040516386b47ce160e01b81525f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906386b47ce1906126df90859087906004016155c2565b602060405180830381865afa1580156126fa573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061271e91906155db565b905061272c82333084612a6b565b604051633d00726360e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690633d0072639061277c9087908690889060040161560d565b6020604051808303815f875af1158015612798573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127bc91906155db565b5050505050565b6001546001600160a01b031633036127d757565b6040516379543eaf60e11b815260040160405180910390fd5b6040516326a7a5ed60e21b81525f906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690639a9e97b49061212890869086906004016155c2565b60018054600160a81b900460ff161515900361193657604051636c1ae47b60e11b815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004015f604051808303818588803b1580156128c8575f80fd5b505af11580156128da573d5f803e3d5ffd5b505050505050565b5f6012545f03612a1a575f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c814d2d16040518163ffffffff1660e01b81526004016020604051808303815f875af115801561294a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061296e91906155db565b90506129798161352b565b60405163095ea7b360e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906129e7907f00000000000000000000000000000000000000000000000000000000000000009085906004016155c2565b5f604051808303815f87803b1580156129fe575f80fd5b505af1158015612a10573d5f803e3d5ffd5b5092949350505050565b601280546015915f919082612a2e8361562c565b9190505581526020019081526020015f2054905090565b5f612a548787878787876135dd565b612a6085878587613670565b979650505050505050565b6040516001600160a01b03808516602483015283166044820152606481018290526127bc9085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526136ad565b612ae08133611717565b1515600114612321575f80fd5b5f612b187f0000000000000000000000000000000000000000000000000000000000000000836134a9565b9050612b45837f000000000000000000000000000000000000000000000000000000000000000084613761565b90506110947f000000000000000000000000000000000000000000000000000000000000000033836137f3565b5f818152600d6020526040812054819060ff16612b9757612b92836130f3565b612ba0565b612ba083613187565b9050805f03612bb25750600192915050565b612bbb83611dbe565b612bc484611411565b10159392505050565b5f80670de0b6b3a7640000851015612be957505f905080611904565b5f612bf48787611c4d565b90505f612c018883615584565b90505f612c0e8287612cf5565b90505f670de0b6b3a7640000612c248a8a61554e565b612c2e9190615565565b90505f670de0b6b3a7640000612c44818c615584565b612c4e908561554e565b612c589190615565565b9050808210155f60018214612c7657612c718484615584565b612c80565b612c808385615584565b9d919c50909a5050505050505050505050565b5f8415612ca857612ca384613187565b612cb1565b612cb1846130f3565b90505f8515612cc857612cc38561320e565b612cd1565b612cd1856131dc565b9050612cec85825f612ce289613439565b8689898d8f613812565b50505050505050565b5f80600183151514612d12576005546001600160a01b0316612d1f565b6006546001600160a01b03165b90505f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632ab88d1c836040518263ffffffff1660e01b8152600401612d6e9190614bf5565b602060405180830381865afa158015612d89573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612dad91906155db565b90505f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663cfdc148f846040518263ffffffff1660e01b8152600401612dfc9190614bf5565b602060405180830381865afa158015612e17573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612e3b91906155db565b905080821115612e50575f9350505050611464565b5f81612e5c8885615584565b612e6e90670de0b6b3a764000061554e565b612e789190615565565b612e8a90670de0b6b3a7640000615584565b90505f612e9685613b8a565b5190505f612ea386613b8a565b6080015190505f612eb48484615584565b612ebe908461554e565b90508084612ed4670de0b6b3a76400008561554e565b612ede919061554e565b612ee89190615565565b9a9950505050505050505050565b5f80612f0185613c42565b5f858152600d602052604081205460ff161515600114612f2c576005546001600160a01b0316612f39565b6006546001600160a01b03165b9050612f458185613c86565b5f878152600d60205260408120549194509060ff161515600114612f9757670de0b6b3a76400006706f05b59d3b20000612f7e896130f3565b612f88919061554e565b612f929190615565565b612fc6565b670de0b6b3a76400006706f05b59d3b20000612fb289613187565b612fbc919061554e565b612fc69190615565565b905080851115612fe95760405163e73233fd60e01b815260040160405180910390fd5b604051631fed9a3160e21b815260048101889052602481018790523360448201526001600160a01b0383811660648301527f00000000000000000000000000000000000000000000000000000000000000008116608483015260a4820186905260c482018790527f00000000000000000000000000000000000000000000000000000000000000001690637fb668c49060e4016020604051808303815f875af1158015613098573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130bc91906155db565b92505050935093915050565b600b546001600160a01b031633146119365760405163075c82fd60e31b815260040160405180910390fd5b600554604051632a145e2560e01b81525f916001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811692632a145e2592613148928792911690600401614bde565b602060405180830381865afa158015613163573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061146491906155db565b600654604051632a145e2560e01b81525f916001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811692632a145e2592613148928792911690600401614bde565b5f806131e7836130f3565b9050801561320857600554613205906001600160a01b031682613c86565b91505b50919050565b5f8061321983613187565b9050805f0361322a57505f92915050565b600654613205906001600160a01b031682613c86565b5f825f0361326157604051630eda9c3d60e31b815260040160405180910390fd5b6001600160a01b038083165f908152601460205260408082209190915551634ef969ed60e01b81527f000000000000000000000000000000000000000000000000000000000000000090911690634ef969ed906132c490859087906004016155c2565b5f604051808303815f87803b1580156132db575f80fd5b505af11580156132ed573d5f803e3d5ffd5b505060108054925090505f61330183615597565b909155505060118054905f6133158361562c565b90915550929392505050565b600154600160b01b900460ff1615155f0361334f5760405163075c82fd60e31b815260040160405180910390fd5b6001805460ff60b01b191690555f82900361337d57604051631e5edc1560e31b815260040160405180910390fd5b6001600160a01b03811673ba12222222228d8ba445958a75a0704d566bf2c81461154c576001600160a01b038116301461154c576040516324ee9bf560e11b815260040160405180910390fd5b5f805f805f805f805f8b8060200190518101906133e7919061568e565b9850985098509850985098509850985098505f8811156134285761341a81838b8b8f61341391906155af565b8e8a613cd6565b505050505050505050505050565b61341a818a888a8e8a8a8a8a613f42565b60405163951e435d60e01b81525f906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063951e435d906131489085907f000000000000000000000000000000000000000000000000000000000000000090600401614bde565b6040516365d5787760e01b81525f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906365d578779061212890869086906004016155c2565b6001600160a01b03821661350c57505050565b61209f8363095ea7b360e01b8484604051602401612a9f9291906155c2565b604051631ace8bcf60e31b815260048101829052600160248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063d6745e78906044015f604051808303815f87803b158015613591575f80fd5b505af11580156135a3573d5f803e3d5ffd5b5050604080518481524260208201527f96e42d3257b3918e5d21803481411046445d8f5ae52841ae17000a2f5cd99190935001905061158e565b6135f0670de0b6b3a7640000600f61554e565b82111561361057604051633a4eb5e560e11b815260040160405180910390fd5b5f61361b8484611c4d565b905061362681614132565b15155f036136475760405163e35477cd60e01b815260040160405180910390fd5b612cec856136558684615584565b865f8087600b60149054906101000a900460ff168d8f613812565b5f8061367c338761416a565b5f878152600d60205260409020805460ff1916871515179055905061170e818786866136a78361163d565b426141dc565b5f805f846001600160a01b0316846040516136c8919061572f565b5f604051808303815f865af19150503d805f8114613701576040519150601f19603f3d011682016040523d82523d5f602084013e613706565b606091505b50915091505f81515f148061372a57508180602001905181019061372a91906155f2565b90508215155f03613739575f80fd5b8280156137435750805b801561184157505f866001600160a01b03163b119695505050505050565b6040516330b9df9160e21b81525f906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c2e77e44906137b39087908790879060040161560d565b6020604051808303815f875af11580156137cf573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116c791906155db565b61209f8363a9059cbb60e01b8484604051602401612a9f9291906155c2565b6040805160018082528183019092525f916020808301908036833750506040805160018082528183019092529293505f92915060208083019080368337505060055484519293506001600160a01b0316918491505f906138745761387461540c565b60200260200101906001600160a01b031690816001600160a01b03168152505089815f815181106138a7576138a761540c565b60209081029190910101526001805460ff60b01b1916600160b01b1790556008546001600160a01b03161561397f5760085f9054906101000a90046001600160a01b03166001600160a01b031663022c0d9f5f8c308f8e8e8e8e338f8f8f60405160200161391d99989796959493929190615773565b6040516020818303038152906040526040518563ffffffff1660e01b815260040161394b94939291906157d3565b5f604051808303815f87803b158015613962575f80fd5b505af1158015613974573d5f803e3d5ffd5b505050505050613b7f565b6009546001600160a01b031615613afe57600f8a905560095460055460408051630dfe168160e01b815290516001600160a01b039384169363490e6cbc9330939116918591630dfe16819160048083019260209291908290030181865afa1580156139ec573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613a1091906153d7565b6001600160a01b031614613a24575f613a26565b8c5b6005546009546040805163d21220a760e01b815290516001600160a01b03938416939092169163d21220a7916004808201926020929091908290030181865afa158015613a75573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613a9991906153d7565b6001600160a01b031614613aad575f613aaf565b8d5b8f8e8e8e8e338f8f8f604051602001613ad099989796959493929190615773565b6040516020818303038152906040526040518563ffffffff1660e01b815260040161394b94939291906157ff565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316635c38449e3084848f8e8e8e8e338f8f8f604051602001613b5199989796959493929190615773565b6040516020818303038152906040526040518563ffffffff1660e01b8152600401611385949392919061582b565b505050505050505050565b613bb76040518060a001604052805f81526020015f81526020015f81526020015f81526020015f81525090565b6040516349622c4960e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906349622c4990613c03908590600401614bf5565b60a060405180830381865afa158015613c1e573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061146491906158c0565b600b54600160a81b900460ff161515600103613c5b5750565b613c6481612b72565b15156001036123215760405163cc71476d60e01b815260040160405180910390fd5b6040516386b47ce160e01b81525f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906386b47ce19061212890869086906004016155c2565b6005545f90613cee906001600160a01b0316856120d8565b90505f613cfc886001614281565b6040516325ca070560e11b8152600481018290529091505f906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690634b940e0a9060240160408051808303815f875af1158015613d64573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613d8891906158da565b5090505f670de0b6b3a764000085613dc07f0000000000000000000000000000000000000000000000000000000000000000856120d8565b613dca919061554e565b613dd49190615565565b905083811015613df75760405163bd19b35560e01b815260040160405180910390fd5b604051636987b14960e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063d30f629290613e67908b907f000000000000000000000000000000000000000000000000000000000000000090879060040161560d565b6020604051808303815f875af1158015613e83573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613ea791906155db565b50613eb38989886142e0565b613ebc88612b72565b15155f03613edd5760405163050135d160e51b815260040160405180910390fd5b46600103613f0b57600554600954613f02916001600160a01b039081169116886137f3565b505050506128da565b600554613f36906001600160a01b031673ba12222222228d8ba445958a75a0704d566bf2c8886137f3565b50505050505050505050565b613f4d8189896143d2565b5f6140b17f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663fe88136e613fce7f00000000000000000000000000000000000000000000000000000000000000006120d38f613439565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166396a3b69a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561402a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061404e91906155db565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401602060405180830381865afa15801561408d573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061144b91906155db565b90506140bd8988614484565b505f6140c98b5f614281565b6005549091505f90670de0b6b3a76400009088906140f0906001600160a01b0316856120d8565b6140fa919061554e565b6141049190615565565b9050828110156141275760405163bd19b35560e01b815260040160405180910390fd5b61341a828988614519565b5f8061415e7f0000000000000000000000000000000000000000000000000000000000000000846120d8565b60035411159392505050565b6001600160a01b0382165f90815260146020526040812054156141a0576040516343d9a50360e11b815260040160405180910390fd5b5f6141a96145f9565b6001600160a01b0385165f9081526014602090815260408083208490558383526013909152902084905591505092915050565b6040805160a08101825286815260208082018781528284018781526060808501888152608086018881525f8e8152600c8752889020875181559451600186015592516002850155516003840155905160049092019190915583518781529182018690529281018490529091869188918a917faa27558e5219d1a6088de4c80bdd26623b70f4424b74f61e9848796442c5a1a8910160405180910390a450505050505050565b5f61428c838361460f565b5f80614297856146e9565b90925090508115155f036142be5760405163dcaf6b0b60e01b815260040160405180910390fd5b5f818060200190518101906142d391906158fc565b5090979650505050505050565b82151560010361437e5760055460405163c7c5c4a760e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169263c7c5c4a79261433e9287921690869060040161560d565b6020604051808303815f875af115801561435a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061209f91906155db565b60055460405163c7c5c4a760e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169263c7c5c4a79261433e9287921690869060040161560d565b82151560010361443057600554604051633d00726360e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811692633d0072639261433e9287921690869060040161560d565b600554604051633d00726360e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811692633d0072639261433e9287921690869060040161560d565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316637d0fedaa6144df857f000000000000000000000000000000000000000000000000000000000000000086613761565b6040518263ffffffff1660e01b81526004016144fd91815260200190565b6020604051808303815f875af1158015612143573d5f803e3d5ffd5b6005546001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116911603614557576145578361286f565b6008545f906001600160a01b03161561457b576008546001600160a01b0316614588565b6009546001600160a01b03165b6005549091506145d9906001600160a01b031673ba12222222228d8ba445958a75a0704d566bf2c71933016145d15773ba12222222228d8ba445958a75a0704d566bf2c86145d3565b825b856137f3565b60055461209f906001600160a01b0316836145f48688615584565b6137f3565b5f614602614774565b60105461202e91906155af565b5f60018215151461462757630306d04360e51b614630565b63092ccd6360e11b5b90505f6001600160e01b03198216614649856020015190565b6001600160e01b0319161490505f81900361469157602084015160405163a509f36b60e01b81526001600160e01b03199182166004820152908316602482015260440161121f565b8215156001036146c4575f805f805f806146aa8a61478d565b955095509550955095509550613f36868686868686614802565b5f805f805f6146d289614866565b94509450945094509450613b7f85858585856148ac565b600b805460ff60b01b1916600160b01b179055600a546040515f916060916001600160a01b039091169061471e90859061572f565b5f604051808303815f865af19150503d805f8114614757576040519150601f19603f3d011682016040523d82523d5f602084013e61475c565b606091505b50600b805460ff60b01b191690559094909350915050565b5f60115f815461478390615597565b9182905550919050565b5f805f6147bd6040518060a001604052805f81526020015f81526020015f81526020015f81526020015f81525090565b6147c5614b3b565b6147cd614ba8565b5f6147d788614910565b9050808060200190518101906147ed9190615c84565b949d939c50919a509850965090945092505050565b61480c86866149c6565b6148268260600151836080015160200151835f0151614a69565b60055482516001600160a01b039081169116146128da5781516005546040516327ceb30960e11b815261121f92916001600160a01b0316906004016153f2565b5f805f614871614b3b565b614879614ba8565b5f61488387614910565b9050808060200190518101906148999190615d25565b939b929a50909850965090945092505050565b6148b685856149c6565b6148d08260600151836080015160200151835f0151614a69565b60055482516001600160a01b039081169116146127bc578151600554604051633568b07360e01b815261121f92916001600160a01b0316906004016153f2565b6060600482516149209190615584565b6001600160401b0381111561493757614937614dc6565b6040519080825280601f01601f191660200182016040528015614961576020820181803683370190505b5090505f5b8151811015613208578261497b8260046155af565b8151811061498b5761498b61540c565b602001015160f81c60f81b8282815181106149a8576149a861540c565b60200101906001600160f81b03191690815f1a905350600101614966565b6001600160a01b03821630146149f357813060405163bb2bcb0160e01b815260040161121f9291906153f2565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b03161461154c57807f0000000000000000000000000000000000000000000000000000000000000000604051635d8e073360e11b815260040161121f9291906153f2565b6001600160a01b0383165f908152600e602052604081205460ff1615159003614aa7578260405163f94e866760e01b815260040161121f9190614bf5565b6001600160a01b03811615614abf57614abf81614afd565b6001600160a01b0382165f908152600e602052604081205460ff1615159003611094578160405163486a4a1560e01b815260040161121f9190614bf5565b6001600160a01b0381165f908152600e602052604081205460ff1615159003612321578060405163b769e9d160e01b815260040161121f9190614bf5565b6040518060a001604052805f6001600160a01b031681526020015f81526020015f6001600160a01b031681526020015f6001600160a01b03168152602001614ba36040805160808101909152805f81525f602082018190526060604083018190529091015290565b905290565b6040518060a001604052805f6001600160a01b031681526020015f81526020016060815260200160608152602001606081525090565b9182526001600160a01b0316602082015260400190565b6001600160a01b0391909116815260200190565b6001600160a01b0381168114612321575f80fd5b5f8083601f840112614c2d575f80fd5b5081356001600160401b03811115614c43575f80fd5b602083019150836020828501011115614c5a575f80fd5b9250929050565b5f805f805f60808688031215614c75575f80fd5b8535614c8081614c09565b9450602086013593506040860135925060608601356001600160401b03811115614ca8575f80fd5b614cb488828901614c1d565b969995985093965092949392505050565b5f805f805f60808688031215614cd9575f80fd5b8535614ce481614c09565b94506020860135614cf481614c09565b93506040860135925060608601356001600160401b03811115614ca8575f80fd5b5f60208284031215614d25575f80fd5b5035919050565b8015158114612321575f80fd5b5f60208284031215614d49575f80fd5b8135611beb81614d2c565b5f8060408385031215614d65575f80fd5b8235614d7081614c09565b91506020830135614d8081614c09565b809150509250929050565b5f60208284031215614d9b575f80fd5b8135611beb81614c09565b5f8060408385031215614db7575f80fd5b50508035926020909101359150565b634e487b7160e01b5f52604160045260245ffd5b60405160a081016001600160401b0381118282101715614dfc57614dfc614dc6565b60405290565b604051608081016001600160401b0381118282101715614dfc57614dfc614dc6565b604051606081016001600160401b0381118282101715614dfc57614dfc614dc6565b60405161018081016001600160401b0381118282101715614dfc57614dfc614dc6565b604051601f8201601f191681016001600160401b0381118282101715614e9157614e91614dc6565b604052919050565b5f6001600160401b03821115614eb157614eb1614dc6565b50601f01601f191660200190565b5f82601f830112614ece575f80fd5b8135614ee1614edc82614e99565b614e69565b818152846020838601011115614ef5575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f8060808587031215614f24575f80fd5b84356001600160401b03811115614f39575f80fd5b614f4587828801614ebf565b9450506020850135614f5681614d2c565b93969395505050506040820135916060013590565b5f8060408385031215614f7c575f80fd5b823591506020830135614d8081614c09565b5f805f805f60a08688031215614fa2575f80fd5b85356001600160401b03811115614fb7575f80fd5b614fc388828901614ebf565b9550506020860135614fd481614d2c565b94979496505050506040830135926060810135926080909101359150565b5f805f8060808587031215615005575f80fd5b843593506020850135925060408501359150606085013561502581614d2c565b939692955090935050565b5f6001600160401b0382111561504857615048614dc6565b5060051b60200190565b5f82601f830112615061575f80fd5b81356020615071614edc83615030565b8083825260208201915060208460051b870101935086841115615092575f80fd5b602086015b848110156150b75780356150aa81614d2c565b8352918301918301615097565b509695505050505050565b5f80604083850312156150d3575f80fd5b82356001600160401b03808211156150e9575f80fd5b818501915085601f8301126150fc575f80fd5b8135602061510c614edc83615030565b82815260059290921b8401810191818101908984111561512a575f80fd5b948201945b8386101561515157853561514281614c09565b8252948201949082019061512f565b96505086013592505080821115615166575f80fd5b5061517385828601615052565b9150509250929050565b5f805f8060808587031215615190575f80fd5b84356001600160401b038111156151a5575f80fd5b6151b187828801614ebf565b9450506020850135925060408501359150606085013561502581614d2c565b5f80604083850312156151e1575f80fd5b823591506020830135614d8081614d2c565b5f805f60608486031215615205575f80fd5b505081359360208301359350604090920135919050565b5f805f806060858703121561522f575f80fd5b843593506020850135925060408501356001600160401b03811115615252575f80fd5b61525e87828801614c1d565b95989497509550505050565b5f82601f830112615279575f80fd5b81356020615289614edc83615030565b8083825260208201915060208460051b8701019350868411156152aa575f80fd5b602086015b848110156150b757803583529183019183016152af565b5f805f80608085870312156152d9575f80fd5b84356001600160401b03808211156152ef575f80fd5b818701915087601f830112615302575f80fd5b81356020615312614edc83615030565b82815260059290921b8401810191818101908b841115615330575f80fd5b948201945b8386101561535757853561534881614c09565b82529482019490820190615335565b9850508801359250508082111561536c575f80fd5b6153788883890161526a565b9450604087013591508082111561538d575f80fd5b6153998883890161526a565b935060608701359150808211156153ae575f80fd5b506153bb87828801614ebf565b91505092959194509250565b80516153d281614c09565b919050565b5f602082840312156153e7575f80fd5b8151611beb81614c09565b6001600160a01b0392831681529116602082015260400190565b634e487b7160e01b5f52603260045260245ffd5b5f815180845260208085019450602084015f5b838110156154585781516001600160a01b031687529582019590820190600101615433565b509495945050505050565b5f815180845260208085019450602084015f5b8381101561545857815187529582019590820190600101615476565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b608081525f6154cc6080830188615420565b82810360208401526154de8188615463565b905082810360408401526154f28187615463565b90508281036060840152611e52818587615492565b6001600160a01b03868116825285166020820152604081018490526080606082018190525f90612a609083018486615492565b634e487b7160e01b5f52601160045260245ffd5b80820281158282048414176114645761146461553a565b5f8261557f57634e487b7160e01b5f52601260045260245ffd5b500490565b818103818111156114645761146461553a565b5f600182016155a8576155a861553a565b5060010190565b808201808211156114645761146461553a565b6001600160a01b03929092168252602082015260400190565b5f602082840312156155eb575f80fd5b5051919050565b5f60208284031215615602575f80fd5b8151611beb81614d2c565b9283526001600160a01b03919091166020830152604082015260600190565b5f8161563a5761563a61553a565b505f190190565b5f82601f830112615650575f80fd5b815161565e614edc82614e99565b818152846020838601011115615672575f80fd5b8160208501602083015e5f918101602001919091529392505050565b5f805f805f805f805f6101208a8c0312156156a7575f80fd5b8951985060208a0151975060408a0151965060608a0151955060808a0151945060a08a01516156d581614c09565b60c08b01519094506156e681614d2c565b60e08b01519093506156f781614d2c565b6101008b01519092506001600160401b03811115615713575f80fd5b61571f8c828d01615641565b9150509295985092959850929598565b5f82518060208501845e5f920191825250919050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f6101208b83528a602084015289604084015288606084015287608084015260018060a01b03871660a084015285151560c084015284151560e0840152806101008401526157c381840185615745565b9c9b505050505050505050505050565b84815283602082015260018060a01b0383166040820152608060608201525f6118416080830184615745565b60018060a01b0385168152836020820152826040820152608060608201525f6118416080830184615745565b6001600160a01b03851681526080602082018190525f9061584e90830186615420565b82810360408401526158608186615463565b90508281036060840152612a608185615745565b5f60a08284031215615884575f80fd5b61588c614dda565b9050815181526020820151602082015260408201516040820152606082015160608201526080820151608082015292915050565b5f60a082840312156158d0575f80fd5b611beb8383615874565b5f80604083850312156158eb575f80fd5b505080516020909101519092909150565b5f805f6060848603121561590e575f80fd5b8351925060208401519150604084015190509250925092565b60048110612321575f80fd5b80516153d281615927565b5f60a0828403121561594e575f80fd5b615956614dda565b9050815161596381614c09565b815260208281015190820152604082015161597d81614c09565b6040820152606082015161599081614c09565b606082015260808201516001600160401b03808211156159ae575f80fd5b90830190608082860312156159c1575f80fd5b6159c9614e02565b82516159d481615927565b815260208301516159e481614c09565b60208201526040830151828111156159fa575f80fd5b615a0687828601615641565b60408301525060608301519250615a1c83614d2c565b606081019290925250608082015292915050565b5f82601f830112615a3f575f80fd5b81516020615a4f614edc83615030565b82815260059290921b84018101918181019086841115615a6d575f80fd5b8286015b848110156150b75780516001600160401b0380821115615a8f575f80fd5b90880190601f196060838c0382011215615aa7575f80fd5b615aaf614e24565b8784015183811115615abf575f80fd5b8401610180818e0384011215615ad3575f80fd5b615adb614e46565b925088810151835260408101518984015260608101516040840152615b0260808201615933565b6060840152615b1360a082016153c7565b6080840152615b2460c082016153c7565b60a0840152615b3560e082016153c7565b60c0840152610100615b488183016153c7565b60e0850152610120808301518286015261014091508183015181860152506101608083015182860152610180830151915085821115615b85575f80fd5b615b938f8c84860101615641565b90850152505090815260408301519082821115615bae575f80fd5b615bbc8c8984870101615641565b8189015260609390930151604084015250508352918301918301615a71565b5f60a08284031215615beb575f80fd5b615bf3614dda565b9050615bfe826153c7565b81526020820151602082015260408201516001600160401b0380821115615c23575f80fd5b615c2f85838601615a30565b60408401526060840151915080821115615c47575f80fd5b615c5385838601615a30565b60608401526080840151915080821115615c6b575f80fd5b50615c7884828501615641565b60808301525092915050565b5f805f805f806101408789031215615c9a575f80fd5b8651615ca581614c09565b6020880151909650615cb681614c09565b60408801519095509350615ccd8860608901615874565b92506101008701516001600160401b0380821115615ce9575f80fd5b615cf58a838b0161593e565b9350610120890151915080821115615d0b575f80fd5b50615d1889828a01615bdb565b9150509295509295509295565b5f805f805f60a08688031215615d39575f80fd5b8551615d4481614c09565b6020870151909550615d5581614c09565b6040870151606088015191955093506001600160401b0380821115615d78575f80fd5b615d8489838a0161593e565b93506080880151915080821115615d99575f80fd5b50615da688828901615bdb565b915050929550929590935056fea2646970667358221220085d1f7160d4a46b24c9b59637c582033900fafc5866187ddd2e7ddf2e86c0d164736f6c6343000819003300000000000000000000000078190e4c7c7b2c2c3b0562f1f155a1fc2f5160ca0000000000000000000000007d93fd973e203cda7a6479ba6a8dbdb2decde320000000000000000000000000888888888889758f76e7103c6cbf23abbf58f946000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000003ee118efc826d30a29645eaf3b2eaac9e8320185000000000000000000000000cdd26eb5eb2ce0f203a84553853667ae69ca29ce000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d2f13f7789f0000000000000000000000000000c917fba41b5247ef115d4490e9b50feb37e28cb7

Deployed Bytecode

0x6080604052600436106103a6575f3560e01c806376c4b7db116101e7578063ba1ad31011610107578063ba1ad31014610cf2578063bb62efbc14610d11578063bc16384614610d44578063bf86d69014610d77578063c157301814610d97578063c27d98fc14610dbf578063c71b0e1c14610dde578063c74c0fac14610df3578063c7aebf5114610e26578063ca3a341a14610e3b578063d18f838f14610e5a578063d3573a3314610eca578063d4f7d90914610ee9578063df011c4114610f09578063e9b2e0d714610f1e578063e9cbafb014610f49578063ec8c890414610f68578063ee97f7f314610f7c578063f04f270714610f9a578063fd41c1d814610fb9575f80fd5b806376c4b7db14610a3257806377314b3714610a47578063798501a914610a665780637a19daea14610a855780637c854ec714610aa557806385dfb48914610ad85780639532ba8514610b035780639751a63f14610b235780639a8a8c5314610b565780639ef2e82d14610b8a5780639f29e7e014610bbd5780639f6cb4dd14610bdc578063a1c44ae014610bfb578063a2309ff814610c1a578063a799566c14610c2f578063a96bb61114610c43578063b56453e414610c62578063b5c2215714610c95578063b5ed298a14610cb4578063b750ee6814610cd3575f80fd5b806341c64a2f116102d257806341c64a2f1461077e57806344b6b11c146107b157806348ccda3c146107d05780634b2a12da146108035780634cacc937146108225780634e71e0c8146108415780634f3823d114610855578063525fbf211461087457806359adab9e146108935780635a5d096c146108a65780635aa6d763146108c55780635ba6b948146108e45780635cb36970146109035780635d4f7742146109375780636016f12d1461094b5780636195af6a1461096b578063627ba5c51461099957806364a1e64b146109b8578063715018a6146109eb578063730e695d146109ff575f80fd5b80623cbb3214610460578063019dbb63146104a957806302eb092a146104d95780630764b9af1461050c5780630dc192da1461052b5780630f61ac82146105525780630f9f234d1461058557806310d1e85c146105b8578063148af2c5146105d7578063150b7a02146105fe5780631b4ff3c3146106365780631bb288e71461065d5780631e183b7a1461068a57806326f4e37d146106a957806327a4986b146106c85780632c5ebc83146106f357806331418fb61461071257806338271bf6146107315780633c97b00d1461075f575f80fd5b3661045c577f49109bdae8e3bbdcbeb7fe5b25b1c75a6bc84fd3f27c6ee0633d41fe197f2aba34336040516103dc929190614bde565b60405180910390a16001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc216330361041657005b60018054600160a01b900460ff161515900361044557604051631976c42360e01b815260040160405180910390fd5b5f5461045a906001600160a01b031634610fe0565b005b5f80fd5b34801561046b575f80fd5b506104937f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b6040516104a09190614bf5565b60405180910390f35b3480156104b4575f80fd5b506001546104c990600160a01b900460ff1681565b60405190151581526020016104a0565b3480156104e4575f80fd5b506104937f0000000000000000000000007d93fd973e203cda7a6479ba6a8dbdb2decde32081565b348015610517575f80fd5b50600754610493906001600160a01b031681565b348015610536575f80fd5b50610493735c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f81565b34801561055d575f80fd5b506104937f000000000000000000000000cdd26eb5eb2ce0f203a84553853667ae69ca29ce81565b348015610590575f80fd5b506104937f0000000000000000000000008eb1b69fb74c6019c16f43ae93f0fad7ccb9a59d81565b3480156105c3575f80fd5b5061045a6105d2366004614c61565b611099565b3480156105e2575f80fd5b5061049373a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b348015610609575f80fd5b5061061d610618366004614cc5565b6113bf565b6040516001600160e01b031990911681526020016104a0565b348015610641575f80fd5b5061049373af88d065e77c8cc2239327c5edb3a432268e583181565b348015610668575f80fd5b5061067c610677366004614d15565b611411565b6040519081526020016104a0565b348015610695575f80fd5b5061045a6106a4366004614d39565b61146a565b3480156106b4575f80fd5b5061045a6106c3366004614d39565b611490565b3480156106d3575f80fd5b5061067c6106e2366004614d15565b60136020525f908152604090205481565b3480156106fe575f80fd5b50600554610493906001600160a01b031681565b34801561071d575f80fd5b5061045a61072c366004614d54565b6114eb565b34801561073c575f80fd5b506104c961074b366004614d8b565b600e6020525f908152604090205460ff1681565b34801561076a575f80fd5b50600a54610493906001600160a01b031681565b348015610789575f80fd5b506104937f000000000000000000000000000000000000000000000000000000000000000081565b3480156107bc575f80fd5b50600954610493906001600160a01b031681565b3480156107db575f80fd5b506104937f00000000000000000000000087870bca3f3fd6335c3f4ce8392d69350b4fa4e281565b34801561080e575f80fd5b5061045a61081d366004614d15565b611550565b34801561082d575f80fd5b5061045a61083c366004614da6565b611599565b34801561084c575f80fd5b5061045a611622565b348015610860575f80fd5b50600654610493906001600160a01b031681565b34801561087f575f80fd5b5061067c61088e366004614d15565b61163d565b61067c6108a1366004614f11565b6116cf565b3480156108b1575f80fd5b506104c96108c0366004614f6b565b611717565b3480156108d0575f80fd5b5061067c6108df366004614f8e565b6117f3565b3480156108ef575f80fd5b5061045a6108fe366004614da6565b61184b565b34801561090e575f80fd5b5061092261091d366004614ff2565b6118f1565b604080519283529015156020830152016104a0565b348015610942575f80fd5b5061045a61190d565b348015610956575f80fd5b506001546104c990600160b01b900460ff1681565b348015610976575f80fd5b506104c9610985366004614d15565b600d6020525f908152604090205460ff1681565b3480156109a4575f80fd5b5061045a6109b33660046150c2565b611938565b3480156109c3575f80fd5b506104937f000000000000000000000000000000000000000000000000000000000000000081565b3480156109f6575f80fd5b5061045a611a30565b348015610a0a575f80fd5b506104937f0000000000000000000000005b2e35d9deb2962d05a5c7e91939169656dcd1cd81565b348015610a3d575f80fd5b5061067c60125481565b348015610a52575f80fd5b5061045a610a6136600461517d565b611a7c565b348015610a71575f80fd5b5061067c610a803660046151d0565b611be0565b348015610a90575f80fd5b50600b546104c990600160b01b900460ff1681565b348015610ab0575f80fd5b506104937f000000000000000000000000bec57d7ba1fef3f2352cd529c3b40cf2c499952981565b348015610ae3575f80fd5b5061067c610af2366004614d8b565b60146020525f908152604090205481565b348015610b0e575f80fd5b50600b546104c990600160a81b900460ff1681565b348015610b2e575f80fd5b506104937f000000000000000000000000896fc8ffc11cda80cf40c373afa9a22d6e05f2d381565b348015610b61575f80fd5b50610b75610b703660046151f3565b611bf2565b604080519283526020830191909152016104a0565b348015610b95575f80fd5b506104937f00000000000000000000000066a1096c6366b2529274df4f5d8247827fe4cea881565b348015610bc8575f80fd5b50600b54610493906001600160a01b031681565b348015610be7575f80fd5b5061045a610bf6366004614d8b565b611c23565b348015610c06575f80fd5b5061067c610c15366004614da6565b611c4d565b348015610c25575f80fd5b5061067c60105481565b348015610c3a575f80fd5b5061045a611c6b565b348015610c4e575f80fd5b5061067c610c5d366004614d15565b611c85565b348015610c6d575f80fd5b506104937f00000000000000000000000078190e4c7c7b2c2c3b0562f1f155a1fc2f5160ca81565b348015610ca0575f80fd5b5061045a610caf366004614d15565b611d07565b348015610cbf575f80fd5b5061045a610cce366004614d8b565b611d14565b348015610cde575f80fd5b5061067c610ced366004614d15565b611d8e565b348015610cfd575f80fd5b50601754610493906001600160a01b031681565b348015610d1c575f80fd5b506104937f0000000000000000000000003ee118efc826d30a29645eaf3b2eaac9e832018581565b348015610d4f575f80fd5b506104937f000000000000000000000000ba12222222228d8ba445958a75a0704d566bf2c881565b348015610d82575f80fd5b506001546104c990600160a81b900460ff1681565b348015610da2575f80fd5b50610dab606481565b60405162ffffff90911681526020016104a0565b348015610dca575f80fd5b50600854610493906001600160a01b031681565b348015610de9575f80fd5b5061067c60115481565b348015610dfe575f80fd5b506104937f0000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f81565b348015610e31575f80fd5b5061067c60035481565b348015610e46575f80fd5b5061067c610e55366004614d15565b611dbe565b348015610e65575f80fd5b50610ea2610e74366004614d15565b600c6020525f9081526040902080546001820154600283015460038401546004909401549293919290919085565b604080519586526020860194909452928401919091526060830152608082015260a0016104a0565b348015610ed5575f80fd5b50600154610493906001600160a01b031681565b348015610ef4575f80fd5b50600b546104c990600160a01b900460ff1681565b348015610f14575f80fd5b5061067c60025481565b348015610f29575f80fd5b5061067c610f38366004614d15565b60156020525f908152604090205481565b348015610f54575f80fd5b5061045a610f6336600461521c565b611e5e565b348015610f73575f80fd5b5061067c612013565b348015610f87575f80fd5b505f54610493906001600160a01b031681565b348015610fa5575f80fd5b5061045a610fb43660046152c6565b612033565b348015610fc4575f80fd5b5061049373724dc807b04555b71ed48a6896b6f41593b8c63781565b804710156110015760405163617ab12d60e11b815260040160405180910390fd5b6001805460ff60a01b1916600160a01b1790556040515f906001600160a01b0384169083908381818185875af1925050503d805f811461105c576040519150601f19603f3d011682016040523d82523d5f602084013e611061565b606091505b50506001805460ff60a01b1916905590508015155f036110945760405163120086e360e11b815260040160405180910390fd5b505050565b5f336001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110d6573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110fa91906153d7565b90505f336001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611139573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061115d91906153d7565b90505f7f0000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f6001600160a01b031663e6a4390584846040518363ffffffff1660e01b81526004016111ae9291906153f2565b602060405180830381865afa1580156111c9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111ed91906153d7565b6008549091506001600160a01b0316331461122857338160405163d36d48d360e01b815260040161121f9291906153f2565b60405180910390fd5b6001600160a01b03881630146112515760405163d949d27360e01b815260040160405180910390fd5b6040805160018082528183019092525f9160208083019080368337505060055482519293506001600160a01b0316918391505f906112915761129161540c565b6001600160a01b0392909216602092830291909101909101526040805160018082528183019092525f9181602001602082028036833701905050905088156112d957886112db565b875b815f815181106112ed576112ed61540c565b60209081029190910101526040805160018082528183019092525f9181602001602082028036833701905050905061133d825f815181106113305761133061540c565b6020026020010151611d8e565b815f8151811061134f5761134f61540c565b602090810291909101015260405163f04f270760e01b8152309063f04f270790611385908690869086908e908e906004016154ba565b5f604051808303815f87803b15801561139c575f80fd5b505af11580156113ae573d5f803e3d5ffd5b505050505050505050505050505050565b5f7fa05d90f300156ad1b545bc5d8197024456f21d22a708f5af04dd293e3d60525186868686866040516113f7959493929190615507565b60405180910390a150630a85bd0160e11b95945050505050565b5f670de0b6b3a76400006002546114507f0000000000000000000000007d93fd973e203cda7a6479ba6a8dbdb2decde32061144b866120a5565b6120d8565b61145a919061554e565b6114649190615565565b92915050565b611472612167565b600b8054911515600160a81b0260ff60a81b19909216919091179055565b611498612167565b6001805460ff60a81b1916600160a81b831515908102919091179091556040514281527fb9c62307336e3148a6afd10d350797a6544eb07ddfb98cf05f49a4cd55d863639060200160405180910390a250565b6114f3612167565b600a80546001600160a01b038085166001600160a01b031992831617909255600780549284169290911691909117905561154c7f00000000000000000000000078190e4c7c7b2c2c3b0562f1f155a1fc2f5160ca612193565b5050565b611558612167565b6003819055604080518281524260208201527f6d41ef415406b2fbd2e8e6c2fa40f471038209962c13e3e9280a9bdf3219983c91015b60405180910390a150565b6115a1612324565b6115a9612353565b6115b16124c6565b5f828152601360205260409020546115c99082612658565b60135f8381526020019081526020015f2054827fa30b3c2ccf1776c70e08f1e8f7d7eb571fe975803f15f61c7526e7947d7504ff8342604051611616929190918252602082015260400190565b60405180910390a35050565b61162a6127c3565b5f80546001600160a01b03191633179055565b5f8061166c7f0000000000000000000000007d93fd973e203cda7a6479ba6a8dbdb2decde32061144b856120a5565b90505f61167884611dbe565b9050808210156116a85761168c8282615584565b604051631309868760e11b815260040161121f91815260200190565b6005546116c7906001600160a01b03166116c28385615584565b6127f0565b949350505050565b5f6116d8612324565b6116e0612840565b6116e8612353565b6116f06124c6565b6116f93461286f565b61170e85856117066128e2565b348787612a45565b95945050505050565b6001600160a01b0381165f9081526014602052604081205483900361173e57506001611464565b816001600160a01b03167f000000000000000000000000c917fba41b5247ef115d4490e9b50feb37e28cb76001600160a01b0316636352211e856040518263ffffffff1660e01b815260040161179691815260200190565b602060405180830381865afa1580156117b1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117d591906153d7565b6001600160a01b0316036117eb57506001611464565b505f92915050565b5f6117fc612324565b611804612840565b61180c612353565b6118146124c6565b60055461182c906001600160a01b0316333087612a6b565b61184186866118396128e2565b878787612a45565b9695505050505050565b611853612324565b61185b612353565b6118636124c6565b8161186d81612ad6565b5f838152601360205260409020546118858184612aed565b61188e81612b72565b15155f036118af57604051632595e55760e21b815260040160405180910390fd5b60408051848152426020820152829186917f54f4c57f40abbe4603bbaf72e5e1d421b094a958865111157f36f674a40cd69a910160405180910390a350505050565b5f806118ff86868686612bcd565b915091505b94509492505050565b6119367f00000000000000000000000078190e4c7c7b2c2c3b0562f1f155a1fc2f5160ca612193565b565b611940612167565b5f5b8251811015611094576119b1600e8483815181106119625761196261540c565b602002602001015184848151811061197c5761197c61540c565b60200260200101516001600160a01b039091165f9081526020929092526040909120805491151560ff19909216919091179055565b8281815181106119c3576119c361540c565b60200260200101516001600160a01b03167f2f48f3e37e626249e017c7289e8781a491500cbad4dc44fa692573419b5acedd838381518110611a0757611a0761540c565b6020026020010151604051611a20911515815260200190565b60405180910390a2600101611942565b611a38612167565b5f80546001600160a01b0319908116825560018054909116905560405133917f6172baf984ea013d88b784409f46655b96ba7f2ff91bca1ac9bcd27b113e6eb091a2565b611a84612324565b611a8c612353565b611a946124c6565b82611a9e81612ad6565b5f848152601360209081526040808320805490849055338452601490925290912054859003611adb57335f90815260146020526040812055611b51565b6040516390901aa360e01b8152600481018690527f000000000000000000000000c917fba41b5247ef115d4490e9b50feb37e28cb76001600160a01b0316906390901aa3906024015f604051808303815f87803b158015611b3a575f80fd5b505af1158015611b4c573d5f803e3d5ffd5b505050505b8060155f60125f8154611b6390615597565b9182905550815260208082019290925260409081015f90812093909355838352600d909152902054611b9c90879060ff16838787612c93565b60408051858152426020820152829187917f79b2e2d00a00811102e4c45a3a4d9866abcbe9f9471572632098aab13aedb52a910160405180910390a3505050505050565b5f611beb8383612cf5565b9392505050565b5f80611bfc612324565b611c04612353565b611c0c6124c6565b611c17858585612ef6565b91509150935093915050565b611c2b612167565b600980546001600160a01b0319166001600160a01b0392909216919091179055565b5f670de0b6b3a7640000611c61838561554e565b611beb9190615565565b611c736130c8565b600b80546001600160a01b0319169055565b5f818152600d6020526040812054819060ff16611caa57611ca5836130f3565b611cb3565b611cb383613187565b9050805f03611cc457505f92915050565b5f611cce84611411565b9050805f03611ce057505f9392505050565b80670de0b6b3a7640000611cf386611dbe565b611cfd919061554e565b6116c79190615565565b611d0f6130c8565b600255565b611d1c612167565b6001600160a01b038116611d435760405163f2365b5b60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03831690811790915560405133907f322fd6444c59daffa82e4689b7685b6fafc6109a1eff8a6ca10c5a8e3206cda1905f90a350565b5f816103e5611d9f826103e861554e565b611da99190615565565b611db39190615584565b6114649060016155af565b5f805f611dca846130f3565b90508015611dde57611ddb846131dc565b91505b5f611de885613187565b90505f8115611dfd57611dfa8661320e565b90505b5f8315611e1d57600554611e1a906001600160a01b0316866120d8565b90505b815f03611e2e579695505050505050565b6006545f90611e46906001600160a01b0316846120d8565b9050611e5281836155af565b98975050505050505050565b6009546001600160a01b03163314611e9a5760095460405163f50e080b60e01b815261121f9133916001600160a01b03909116906004016153f2565b600154600160b01b900460ff1615155f03611ec85760405163075c82fd60e31b815260040160405180910390fd5b6040805160018082528183019092525f9160208083019080368337505060055482519293506001600160a01b0316918391505f90611f0857611f0861540c565b6001600160a01b0392909216602092830291909101909101526040805160018082528183019092525f91816020016020820280368337019050509050600f54815f81518110611f5957611f5961540c565b60209081029190910101526040805160018082528183019092525f918160200160208202803683370190505090508615611f935786611f95565b855b815f81518110611fa757611fa761540c565b602090810291909101015260405163f04f270760e01b8152309063f04f270790611fdd908690869086908b908b906004016154ba565b5f604051808303815f87803b158015611ff4575f80fd5b505af1158015612006573d5f803e3d5ffd5b5050505050505050505050565b335f81815260146020526040812054909161202e9190613240565b905090565b61203e845133613321565b61209f81845f815181106120545761205461540c565b6020026020010151845f8151811061206e5761206e61540c565b6020026020010151865f815181106120885761208861540c565b602002602001015161209a91906155af565b6133ca565b50505050565b5f6114647f0000000000000000000000007d93fd973e203cda7a6479ba6a8dbdb2decde3206120d384613439565b6134a9565b604051630e8f811d60e41b81525f906001600160a01b037f000000000000000000000000896fc8ffc11cda80cf40c373afa9a22d6e05f2d3169063e8f811d09061212890869086906004016155c2565b602060405180830381865afa158015612143573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611beb91906155db565b5f546001600160a01b0316330361217a57565b604051635a7617f960e11b815260040160405180910390fd5b6006546121ab906001600160a01b0316825f196134f9565b6005546007546121c9916001600160a01b0390811691165f196134f9565b600754612202907f000000000000000000000000cdd26eb5eb2ce0f203a84553853667ae69ca29ce906001600160a01b03165f196134f9565b600a5461223b907f000000000000000000000000cdd26eb5eb2ce0f203a84553853667ae69ca29ce906001600160a01b03165f196134f9565b600554612253906001600160a01b0316825f196134f9565b61227f7f0000000000000000000000007d93fd973e203cda7a6479ba6a8dbdb2decde320825f196134f9565b6122cb7f000000000000000000000000cdd26eb5eb2ce0f203a84553853667ae69ca29ce7f0000000000000000000000007d93fd973e203cda7a6479ba6a8dbdb2decde3205f196134f9565b600554612303906001600160a01b03167f0000000000000000000000005b2e35d9deb2962d05a5c7e91939169656dcd1cd5f196134f9565b600554600a54612321916001600160a01b0390811691165f196134f9565b50565b600b54600160b01b900460ff1615156001036119365760405163391c8dbd60e01b815260040160405180910390fd5b60018054600160a01b900460ff16151590036123825760405163075c82fd60e31b815260040160405180910390fd5b7f00000000000000000000000078190e4c7c7b2c2c3b0562f1f155a1fc2f5160ca6001600160a01b031663019dbb636040518163ffffffff1660e01b8152600401602060405180830381865afa1580156123de573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061240291906155f2565b15156001036124245760405163075c82fd60e31b815260040160405180910390fd5b7f0000000000000000000000005b2e35d9deb2962d05a5c7e91939169656dcd1cd6001600160a01b0316631786ef6d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612480573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124a491906155f2565b15156001036119365760405163075c82fd60e31b815260040160405180910390fd5b600554604051631ff631c360e11b81526001600160a01b037f00000000000000000000000078190e4c7c7b2c2c3b0562f1f155a1fc2f5160ca811692633fec638692612519929190911690600401614bf5565b5f604051808303815f87803b158015612530575f80fd5b505af1158015612542573d5f803e3d5ffd5b5050600654604051631ff631c360e11b81526001600160a01b037f00000000000000000000000078190e4c7c7b2c2c3b0562f1f155a1fc2f5160ca81169450633fec63869350612596921690600401614bf5565b5f604051808303815f87803b1580156125ad575f80fd5b505af11580156125bf573d5f803e3d5ffd5b5050604051631ff631c360e11b81526001600160a01b037f00000000000000000000000078190e4c7c7b2c2c3b0562f1f155a1fc2f5160ca169250633fec6386915061262f907f0000000000000000000000007d93fd973e203cda7a6479ba6a8dbdb2decde32090600401614bf5565b5f604051808303815f87803b158015612646575f80fd5b505af115801561209f573d5f803e3d5ffd5b6005545f838152600d60205260409020546001600160a01b039091169060ff16151560010361268f57506006546001600160a01b03165b6040516386b47ce160e01b81525f906001600160a01b037f00000000000000000000000078190e4c7c7b2c2c3b0562f1f155a1fc2f5160ca16906386b47ce1906126df90859087906004016155c2565b602060405180830381865afa1580156126fa573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061271e91906155db565b905061272c82333084612a6b565b604051633d00726360e01b81526001600160a01b037f00000000000000000000000078190e4c7c7b2c2c3b0562f1f155a1fc2f5160ca1690633d0072639061277c9087908690889060040161560d565b6020604051808303815f875af1158015612798573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127bc91906155db565b5050505050565b6001546001600160a01b031633036127d757565b6040516379543eaf60e11b815260040160405180910390fd5b6040516326a7a5ed60e21b81525f906001600160a01b037f000000000000000000000000896fc8ffc11cda80cf40c373afa9a22d6e05f2d31690639a9e97b49061212890869086906004016155c2565b60018054600160a81b900460ff161515900361193657604051636c1ae47b60e11b815260040160405180910390fd5b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004015f604051808303818588803b1580156128c8575f80fd5b505af11580156128da573d5f803e3d5ffd5b505050505050565b5f6012545f03612a1a575f7f000000000000000000000000bec57d7ba1fef3f2352cd529c3b40cf2c49995296001600160a01b031663c814d2d16040518163ffffffff1660e01b81526004016020604051808303815f875af115801561294a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061296e91906155db565b90506129798161352b565b60405163095ea7b360e01b81526001600160a01b037f000000000000000000000000bec57d7ba1fef3f2352cd529c3b40cf2c4999529169063095ea7b3906129e7907f0000000000000000000000005b2e35d9deb2962d05a5c7e91939169656dcd1cd9085906004016155c2565b5f604051808303815f87803b1580156129fe575f80fd5b505af1158015612a10573d5f803e3d5ffd5b5092949350505050565b601280546015915f919082612a2e8361562c565b9190505581526020019081526020015f2054905090565b5f612a548787878787876135dd565b612a6085878587613670565b979650505050505050565b6040516001600160a01b03808516602483015283166044820152606481018290526127bc9085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526136ad565b612ae08133611717565b1515600114612321575f80fd5b5f612b187f0000000000000000000000007d93fd973e203cda7a6479ba6a8dbdb2decde320836134a9565b9050612b45837f0000000000000000000000007d93fd973e203cda7a6479ba6a8dbdb2decde32084613761565b90506110947f0000000000000000000000007d93fd973e203cda7a6479ba6a8dbdb2decde32033836137f3565b5f818152600d6020526040812054819060ff16612b9757612b92836130f3565b612ba0565b612ba083613187565b9050805f03612bb25750600192915050565b612bbb83611dbe565b612bc484611411565b10159392505050565b5f80670de0b6b3a7640000851015612be957505f905080611904565b5f612bf48787611c4d565b90505f612c018883615584565b90505f612c0e8287612cf5565b90505f670de0b6b3a7640000612c248a8a61554e565b612c2e9190615565565b90505f670de0b6b3a7640000612c44818c615584565b612c4e908561554e565b612c589190615565565b9050808210155f60018214612c7657612c718484615584565b612c80565b612c808385615584565b9d919c50909a5050505050505050505050565b5f8415612ca857612ca384613187565b612cb1565b612cb1846130f3565b90505f8515612cc857612cc38561320e565b612cd1565b612cd1856131dc565b9050612cec85825f612ce289613439565b8689898d8f613812565b50505050505050565b5f80600183151514612d12576005546001600160a01b0316612d1f565b6006546001600160a01b03165b90505f7f00000000000000000000000078190e4c7c7b2c2c3b0562f1f155a1fc2f5160ca6001600160a01b0316632ab88d1c836040518263ffffffff1660e01b8152600401612d6e9190614bf5565b602060405180830381865afa158015612d89573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612dad91906155db565b90505f7f00000000000000000000000078190e4c7c7b2c2c3b0562f1f155a1fc2f5160ca6001600160a01b031663cfdc148f846040518263ffffffff1660e01b8152600401612dfc9190614bf5565b602060405180830381865afa158015612e17573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612e3b91906155db565b905080821115612e50575f9350505050611464565b5f81612e5c8885615584565b612e6e90670de0b6b3a764000061554e565b612e789190615565565b612e8a90670de0b6b3a7640000615584565b90505f612e9685613b8a565b5190505f612ea386613b8a565b6080015190505f612eb48484615584565b612ebe908461554e565b90508084612ed4670de0b6b3a76400008561554e565b612ede919061554e565b612ee89190615565565b9a9950505050505050505050565b5f80612f0185613c42565b5f858152600d602052604081205460ff161515600114612f2c576005546001600160a01b0316612f39565b6006546001600160a01b03165b9050612f458185613c86565b5f878152600d60205260408120549194509060ff161515600114612f9757670de0b6b3a76400006706f05b59d3b20000612f7e896130f3565b612f88919061554e565b612f929190615565565b612fc6565b670de0b6b3a76400006706f05b59d3b20000612fb289613187565b612fbc919061554e565b612fc69190615565565b905080851115612fe95760405163e73233fd60e01b815260040160405180910390fd5b604051631fed9a3160e21b815260048101889052602481018790523360448201526001600160a01b0383811660648301527f0000000000000000000000007d93fd973e203cda7a6479ba6a8dbdb2decde3208116608483015260a4820186905260c482018790527f00000000000000000000000078190e4c7c7b2c2c3b0562f1f155a1fc2f5160ca1690637fb668c49060e4016020604051808303815f875af1158015613098573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130bc91906155db565b92505050935093915050565b600b546001600160a01b031633146119365760405163075c82fd60e31b815260040160405180910390fd5b600554604051632a145e2560e01b81525f916001600160a01b037f00000000000000000000000078190e4c7c7b2c2c3b0562f1f155a1fc2f5160ca811692632a145e2592613148928792911690600401614bde565b602060405180830381865afa158015613163573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061146491906155db565b600654604051632a145e2560e01b81525f916001600160a01b037f00000000000000000000000078190e4c7c7b2c2c3b0562f1f155a1fc2f5160ca811692632a145e2592613148928792911690600401614bde565b5f806131e7836130f3565b9050801561320857600554613205906001600160a01b031682613c86565b91505b50919050565b5f8061321983613187565b9050805f0361322a57505f92915050565b600654613205906001600160a01b031682613c86565b5f825f0361326157604051630eda9c3d60e31b815260040160405180910390fd5b6001600160a01b038083165f908152601460205260408082209190915551634ef969ed60e01b81527f000000000000000000000000c917fba41b5247ef115d4490e9b50feb37e28cb790911690634ef969ed906132c490859087906004016155c2565b5f604051808303815f87803b1580156132db575f80fd5b505af11580156132ed573d5f803e3d5ffd5b505060108054925090505f61330183615597565b909155505060118054905f6133158361562c565b90915550929392505050565b600154600160b01b900460ff1615155f0361334f5760405163075c82fd60e31b815260040160405180910390fd5b6001805460ff60b01b191690555f82900361337d57604051631e5edc1560e31b815260040160405180910390fd5b6001600160a01b03811673ba12222222228d8ba445958a75a0704d566bf2c81461154c576001600160a01b038116301461154c576040516324ee9bf560e11b815260040160405180910390fd5b5f805f805f805f805f8b8060200190518101906133e7919061568e565b9850985098509850985098509850985098505f8811156134285761341a81838b8b8f61341391906155af565b8e8a613cd6565b505050505050505050505050565b61341a818a888a8e8a8a8a8a613f42565b60405163951e435d60e01b81525f906001600160a01b037f00000000000000000000000078190e4c7c7b2c2c3b0562f1f155a1fc2f5160ca169063951e435d906131489085907f0000000000000000000000007d93fd973e203cda7a6479ba6a8dbdb2decde32090600401614bde565b6040516365d5787760e01b81525f906001600160a01b037f00000000000000000000000078190e4c7c7b2c2c3b0562f1f155a1fc2f5160ca16906365d578779061212890869086906004016155c2565b6001600160a01b03821661350c57505050565b61209f8363095ea7b360e01b8484604051602401612a9f9291906155c2565b604051631ace8bcf60e31b815260048101829052600160248201527f00000000000000000000000078190e4c7c7b2c2c3b0562f1f155a1fc2f5160ca6001600160a01b03169063d6745e78906044015f604051808303815f87803b158015613591575f80fd5b505af11580156135a3573d5f803e3d5ffd5b5050604080518481524260208201527f96e42d3257b3918e5d21803481411046445d8f5ae52841ae17000a2f5cd99190935001905061158e565b6135f0670de0b6b3a7640000600f61554e565b82111561361057604051633a4eb5e560e11b815260040160405180910390fd5b5f61361b8484611c4d565b905061362681614132565b15155f036136475760405163e35477cd60e01b815260040160405180910390fd5b612cec856136558684615584565b865f8087600b60149054906101000a900460ff168d8f613812565b5f8061367c338761416a565b5f878152600d60205260409020805460ff1916871515179055905061170e818786866136a78361163d565b426141dc565b5f805f846001600160a01b0316846040516136c8919061572f565b5f604051808303815f865af19150503d805f8114613701576040519150601f19603f3d011682016040523d82523d5f602084013e613706565b606091505b50915091505f81515f148061372a57508180602001905181019061372a91906155f2565b90508215155f03613739575f80fd5b8280156137435750805b801561184157505f866001600160a01b03163b119695505050505050565b6040516330b9df9160e21b81525f906001600160a01b037f00000000000000000000000078190e4c7c7b2c2c3b0562f1f155a1fc2f5160ca169063c2e77e44906137b39087908790879060040161560d565b6020604051808303815f875af11580156137cf573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116c791906155db565b61209f8363a9059cbb60e01b8484604051602401612a9f9291906155c2565b6040805160018082528183019092525f916020808301908036833750506040805160018082528183019092529293505f92915060208083019080368337505060055484519293506001600160a01b0316918491505f906138745761387461540c565b60200260200101906001600160a01b031690816001600160a01b03168152505089815f815181106138a7576138a761540c565b60209081029190910101526001805460ff60b01b1916600160b01b1790556008546001600160a01b03161561397f5760085f9054906101000a90046001600160a01b03166001600160a01b031663022c0d9f5f8c308f8e8e8e8e338f8f8f60405160200161391d99989796959493929190615773565b6040516020818303038152906040526040518563ffffffff1660e01b815260040161394b94939291906157d3565b5f604051808303815f87803b158015613962575f80fd5b505af1158015613974573d5f803e3d5ffd5b505050505050613b7f565b6009546001600160a01b031615613afe57600f8a905560095460055460408051630dfe168160e01b815290516001600160a01b039384169363490e6cbc9330939116918591630dfe16819160048083019260209291908290030181865afa1580156139ec573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613a1091906153d7565b6001600160a01b031614613a24575f613a26565b8c5b6005546009546040805163d21220a760e01b815290516001600160a01b03938416939092169163d21220a7916004808201926020929091908290030181865afa158015613a75573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613a9991906153d7565b6001600160a01b031614613aad575f613aaf565b8d5b8f8e8e8e8e338f8f8f604051602001613ad099989796959493929190615773565b6040516020818303038152906040526040518563ffffffff1660e01b815260040161394b94939291906157ff565b7f000000000000000000000000ba12222222228d8ba445958a75a0704d566bf2c86001600160a01b0316635c38449e3084848f8e8e8e8e338f8f8f604051602001613b5199989796959493929190615773565b6040516020818303038152906040526040518563ffffffff1660e01b8152600401611385949392919061582b565b505050505050505050565b613bb76040518060a001604052805f81526020015f81526020015f81526020015f81526020015f81525090565b6040516349622c4960e01b81526001600160a01b037f00000000000000000000000078190e4c7c7b2c2c3b0562f1f155a1fc2f5160ca16906349622c4990613c03908590600401614bf5565b60a060405180830381865afa158015613c1e573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061146491906158c0565b600b54600160a81b900460ff161515600103613c5b5750565b613c6481612b72565b15156001036123215760405163cc71476d60e01b815260040160405180910390fd5b6040516386b47ce160e01b81525f906001600160a01b037f00000000000000000000000078190e4c7c7b2c2c3b0562f1f155a1fc2f5160ca16906386b47ce19061212890869086906004016155c2565b6005545f90613cee906001600160a01b0316856120d8565b90505f613cfc886001614281565b6040516325ca070560e11b8152600481018290529091505f906001600160a01b037f0000000000000000000000007d93fd973e203cda7a6479ba6a8dbdb2decde3201690634b940e0a9060240160408051808303815f875af1158015613d64573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613d8891906158da565b5090505f670de0b6b3a764000085613dc07f0000000000000000000000007d93fd973e203cda7a6479ba6a8dbdb2decde320856120d8565b613dca919061554e565b613dd49190615565565b905083811015613df75760405163bd19b35560e01b815260040160405180910390fd5b604051636987b14960e11b81526001600160a01b037f00000000000000000000000078190e4c7c7b2c2c3b0562f1f155a1fc2f5160ca169063d30f629290613e67908b907f0000000000000000000000007d93fd973e203cda7a6479ba6a8dbdb2decde32090879060040161560d565b6020604051808303815f875af1158015613e83573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613ea791906155db565b50613eb38989886142e0565b613ebc88612b72565b15155f03613edd5760405163050135d160e51b815260040160405180910390fd5b46600103613f0b57600554600954613f02916001600160a01b039081169116886137f3565b505050506128da565b600554613f36906001600160a01b031673ba12222222228d8ba445958a75a0704d566bf2c8886137f3565b50505050505050505050565b613f4d8189896143d2565b5f6140b17f0000000000000000000000007d93fd973e203cda7a6479ba6a8dbdb2decde3207f0000000000000000000000007d93fd973e203cda7a6479ba6a8dbdb2decde3206001600160a01b031663fe88136e613fce7f0000000000000000000000007d93fd973e203cda7a6479ba6a8dbdb2decde3206120d38f613439565b7f0000000000000000000000007d93fd973e203cda7a6479ba6a8dbdb2decde3206001600160a01b03166396a3b69a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561402a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061404e91906155db565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401602060405180830381865afa15801561408d573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061144b91906155db565b90506140bd8988614484565b505f6140c98b5f614281565b6005549091505f90670de0b6b3a76400009088906140f0906001600160a01b0316856120d8565b6140fa919061554e565b6141049190615565565b9050828110156141275760405163bd19b35560e01b815260040160405180910390fd5b61341a828988614519565b5f8061415e7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48846120d8565b60035411159392505050565b6001600160a01b0382165f90815260146020526040812054156141a0576040516343d9a50360e11b815260040160405180910390fd5b5f6141a96145f9565b6001600160a01b0385165f9081526014602090815260408083208490558383526013909152902084905591505092915050565b6040805160a08101825286815260208082018781528284018781526060808501888152608086018881525f8e8152600c8752889020875181559451600186015592516002850155516003840155905160049092019190915583518781529182018690529281018490529091869188918a917faa27558e5219d1a6088de4c80bdd26623b70f4424b74f61e9848796442c5a1a8910160405180910390a450505050505050565b5f61428c838361460f565b5f80614297856146e9565b90925090508115155f036142be5760405163dcaf6b0b60e01b815260040160405180910390fd5b5f818060200190518101906142d391906158fc565b5090979650505050505050565b82151560010361437e5760055460405163c7c5c4a760e01b81526001600160a01b037f0000000000000000000000005b2e35d9deb2962d05a5c7e91939169656dcd1cd81169263c7c5c4a79261433e9287921690869060040161560d565b6020604051808303815f875af115801561435a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061209f91906155db565b60055460405163c7c5c4a760e01b81526001600160a01b037f00000000000000000000000078190e4c7c7b2c2c3b0562f1f155a1fc2f5160ca81169263c7c5c4a79261433e9287921690869060040161560d565b82151560010361443057600554604051633d00726360e01b81526001600160a01b037f0000000000000000000000005b2e35d9deb2962d05a5c7e91939169656dcd1cd811692633d0072639261433e9287921690869060040161560d565b600554604051633d00726360e01b81526001600160a01b037f00000000000000000000000078190e4c7c7b2c2c3b0562f1f155a1fc2f5160ca811692633d0072639261433e9287921690869060040161560d565b5f7f0000000000000000000000007d93fd973e203cda7a6479ba6a8dbdb2decde3206001600160a01b0316637d0fedaa6144df857f0000000000000000000000007d93fd973e203cda7a6479ba6a8dbdb2decde32086613761565b6040518263ffffffff1660e01b81526004016144fd91815260200190565b6020604051808303815f875af1158015612143573d5f803e3d5ffd5b6005546001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28116911603614557576145578361286f565b6008545f906001600160a01b03161561457b576008546001600160a01b0316614588565b6009546001600160a01b03165b6005549091506145d9906001600160a01b031673ba12222222228d8ba445958a75a0704d566bf2c71933016145d15773ba12222222228d8ba445958a75a0704d566bf2c86145d3565b825b856137f3565b60055461209f906001600160a01b0316836145f48688615584565b6137f3565b5f614602614774565b60105461202e91906155af565b5f60018215151461462757630306d04360e51b614630565b63092ccd6360e11b5b90505f6001600160e01b03198216614649856020015190565b6001600160e01b0319161490505f81900361469157602084015160405163a509f36b60e01b81526001600160e01b03199182166004820152908316602482015260440161121f565b8215156001036146c4575f805f805f806146aa8a61478d565b955095509550955095509550613f36868686868686614802565b5f805f805f6146d289614866565b94509450945094509450613b7f85858585856148ac565b600b805460ff60b01b1916600160b01b179055600a546040515f916060916001600160a01b039091169061471e90859061572f565b5f604051808303815f865af19150503d805f8114614757576040519150601f19603f3d011682016040523d82523d5f602084013e61475c565b606091505b50600b805460ff60b01b191690559094909350915050565b5f60115f815461478390615597565b9182905550919050565b5f805f6147bd6040518060a001604052805f81526020015f81526020015f81526020015f81526020015f81525090565b6147c5614b3b565b6147cd614ba8565b5f6147d788614910565b9050808060200190518101906147ed9190615c84565b949d939c50919a509850965090945092505050565b61480c86866149c6565b6148268260600151836080015160200151835f0151614a69565b60055482516001600160a01b039081169116146128da5781516005546040516327ceb30960e11b815261121f92916001600160a01b0316906004016153f2565b5f805f614871614b3b565b614879614ba8565b5f61488387614910565b9050808060200190518101906148999190615d25565b939b929a50909850965090945092505050565b6148b685856149c6565b6148d08260600151836080015160200151835f0151614a69565b60055482516001600160a01b039081169116146127bc578151600554604051633568b07360e01b815261121f92916001600160a01b0316906004016153f2565b6060600482516149209190615584565b6001600160401b0381111561493757614937614dc6565b6040519080825280601f01601f191660200182016040528015614961576020820181803683370190505b5090505f5b8151811015613208578261497b8260046155af565b8151811061498b5761498b61540c565b602001015160f81c60f81b8282815181106149a8576149a861540c565b60200101906001600160f81b03191690815f1a905350600101614966565b6001600160a01b03821630146149f357813060405163bb2bcb0160e01b815260040161121f9291906153f2565b7f000000000000000000000000cdd26eb5eb2ce0f203a84553853667ae69ca29ce6001600160a01b0316816001600160a01b03161461154c57807f000000000000000000000000cdd26eb5eb2ce0f203a84553853667ae69ca29ce604051635d8e073360e11b815260040161121f9291906153f2565b6001600160a01b0383165f908152600e602052604081205460ff1615159003614aa7578260405163f94e866760e01b815260040161121f9190614bf5565b6001600160a01b03811615614abf57614abf81614afd565b6001600160a01b0382165f908152600e602052604081205460ff1615159003611094578160405163486a4a1560e01b815260040161121f9190614bf5565b6001600160a01b0381165f908152600e602052604081205460ff1615159003612321578060405163b769e9d160e01b815260040161121f9190614bf5565b6040518060a001604052805f6001600160a01b031681526020015f81526020015f6001600160a01b031681526020015f6001600160a01b03168152602001614ba36040805160808101909152805f81525f602082018190526060604083018190529091015290565b905290565b6040518060a001604052805f6001600160a01b031681526020015f81526020016060815260200160608152602001606081525090565b9182526001600160a01b0316602082015260400190565b6001600160a01b0391909116815260200190565b6001600160a01b0381168114612321575f80fd5b5f8083601f840112614c2d575f80fd5b5081356001600160401b03811115614c43575f80fd5b602083019150836020828501011115614c5a575f80fd5b9250929050565b5f805f805f60808688031215614c75575f80fd5b8535614c8081614c09565b9450602086013593506040860135925060608601356001600160401b03811115614ca8575f80fd5b614cb488828901614c1d565b969995985093965092949392505050565b5f805f805f60808688031215614cd9575f80fd5b8535614ce481614c09565b94506020860135614cf481614c09565b93506040860135925060608601356001600160401b03811115614ca8575f80fd5b5f60208284031215614d25575f80fd5b5035919050565b8015158114612321575f80fd5b5f60208284031215614d49575f80fd5b8135611beb81614d2c565b5f8060408385031215614d65575f80fd5b8235614d7081614c09565b91506020830135614d8081614c09565b809150509250929050565b5f60208284031215614d9b575f80fd5b8135611beb81614c09565b5f8060408385031215614db7575f80fd5b50508035926020909101359150565b634e487b7160e01b5f52604160045260245ffd5b60405160a081016001600160401b0381118282101715614dfc57614dfc614dc6565b60405290565b604051608081016001600160401b0381118282101715614dfc57614dfc614dc6565b604051606081016001600160401b0381118282101715614dfc57614dfc614dc6565b60405161018081016001600160401b0381118282101715614dfc57614dfc614dc6565b604051601f8201601f191681016001600160401b0381118282101715614e9157614e91614dc6565b604052919050565b5f6001600160401b03821115614eb157614eb1614dc6565b50601f01601f191660200190565b5f82601f830112614ece575f80fd5b8135614ee1614edc82614e99565b614e69565b818152846020838601011115614ef5575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f8060808587031215614f24575f80fd5b84356001600160401b03811115614f39575f80fd5b614f4587828801614ebf565b9450506020850135614f5681614d2c565b93969395505050506040820135916060013590565b5f8060408385031215614f7c575f80fd5b823591506020830135614d8081614c09565b5f805f805f60a08688031215614fa2575f80fd5b85356001600160401b03811115614fb7575f80fd5b614fc388828901614ebf565b9550506020860135614fd481614d2c565b94979496505050506040830135926060810135926080909101359150565b5f805f8060808587031215615005575f80fd5b843593506020850135925060408501359150606085013561502581614d2c565b939692955090935050565b5f6001600160401b0382111561504857615048614dc6565b5060051b60200190565b5f82601f830112615061575f80fd5b81356020615071614edc83615030565b8083825260208201915060208460051b870101935086841115615092575f80fd5b602086015b848110156150b75780356150aa81614d2c565b8352918301918301615097565b509695505050505050565b5f80604083850312156150d3575f80fd5b82356001600160401b03808211156150e9575f80fd5b818501915085601f8301126150fc575f80fd5b8135602061510c614edc83615030565b82815260059290921b8401810191818101908984111561512a575f80fd5b948201945b8386101561515157853561514281614c09565b8252948201949082019061512f565b96505086013592505080821115615166575f80fd5b5061517385828601615052565b9150509250929050565b5f805f8060808587031215615190575f80fd5b84356001600160401b038111156151a5575f80fd5b6151b187828801614ebf565b9450506020850135925060408501359150606085013561502581614d2c565b5f80604083850312156151e1575f80fd5b823591506020830135614d8081614d2c565b5f805f60608486031215615205575f80fd5b505081359360208301359350604090920135919050565b5f805f806060858703121561522f575f80fd5b843593506020850135925060408501356001600160401b03811115615252575f80fd5b61525e87828801614c1d565b95989497509550505050565b5f82601f830112615279575f80fd5b81356020615289614edc83615030565b8083825260208201915060208460051b8701019350868411156152aa575f80fd5b602086015b848110156150b757803583529183019183016152af565b5f805f80608085870312156152d9575f80fd5b84356001600160401b03808211156152ef575f80fd5b818701915087601f830112615302575f80fd5b81356020615312614edc83615030565b82815260059290921b8401810191818101908b841115615330575f80fd5b948201945b8386101561535757853561534881614c09565b82529482019490820190615335565b9850508801359250508082111561536c575f80fd5b6153788883890161526a565b9450604087013591508082111561538d575f80fd5b6153998883890161526a565b935060608701359150808211156153ae575f80fd5b506153bb87828801614ebf565b91505092959194509250565b80516153d281614c09565b919050565b5f602082840312156153e7575f80fd5b8151611beb81614c09565b6001600160a01b0392831681529116602082015260400190565b634e487b7160e01b5f52603260045260245ffd5b5f815180845260208085019450602084015f5b838110156154585781516001600160a01b031687529582019590820190600101615433565b509495945050505050565b5f815180845260208085019450602084015f5b8381101561545857815187529582019590820190600101615476565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b608081525f6154cc6080830188615420565b82810360208401526154de8188615463565b905082810360408401526154f28187615463565b90508281036060840152611e52818587615492565b6001600160a01b03868116825285166020820152604081018490526080606082018190525f90612a609083018486615492565b634e487b7160e01b5f52601160045260245ffd5b80820281158282048414176114645761146461553a565b5f8261557f57634e487b7160e01b5f52601260045260245ffd5b500490565b818103818111156114645761146461553a565b5f600182016155a8576155a861553a565b5060010190565b808201808211156114645761146461553a565b6001600160a01b03929092168252602082015260400190565b5f602082840312156155eb575f80fd5b5051919050565b5f60208284031215615602575f80fd5b8151611beb81614d2c565b9283526001600160a01b03919091166020830152604082015260600190565b5f8161563a5761563a61553a565b505f190190565b5f82601f830112615650575f80fd5b815161565e614edc82614e99565b818152846020838601011115615672575f80fd5b8160208501602083015e5f918101602001919091529392505050565b5f805f805f805f805f6101208a8c0312156156a7575f80fd5b8951985060208a0151975060408a0151965060608a0151955060808a0151945060a08a01516156d581614c09565b60c08b01519094506156e681614d2c565b60e08b01519093506156f781614d2c565b6101008b01519092506001600160401b03811115615713575f80fd5b61571f8c828d01615641565b9150509295985092959850929598565b5f82518060208501845e5f920191825250919050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f6101208b83528a602084015289604084015288606084015287608084015260018060a01b03871660a084015285151560c084015284151560e0840152806101008401526157c381840185615745565b9c9b505050505050505050505050565b84815283602082015260018060a01b0383166040820152608060608201525f6118416080830184615745565b60018060a01b0385168152836020820152826040820152608060608201525f6118416080830184615745565b6001600160a01b03851681526080602082018190525f9061584e90830186615420565b82810360408401526158608186615463565b90508281036060840152612a608185615745565b5f60a08284031215615884575f80fd5b61588c614dda565b9050815181526020820151602082015260408201516040820152606082015160608201526080820151608082015292915050565b5f60a082840312156158d0575f80fd5b611beb8383615874565b5f80604083850312156158eb575f80fd5b505080516020909101519092909150565b5f805f6060848603121561590e575f80fd5b8351925060208401519150604084015190509250925092565b60048110612321575f80fd5b80516153d281615927565b5f60a0828403121561594e575f80fd5b615956614dda565b9050815161596381614c09565b815260208281015190820152604082015161597d81614c09565b6040820152606082015161599081614c09565b606082015260808201516001600160401b03808211156159ae575f80fd5b90830190608082860312156159c1575f80fd5b6159c9614e02565b82516159d481615927565b815260208301516159e481614c09565b60208201526040830151828111156159fa575f80fd5b615a0687828601615641565b60408301525060608301519250615a1c83614d2c565b606081019290925250608082015292915050565b5f82601f830112615a3f575f80fd5b81516020615a4f614edc83615030565b82815260059290921b84018101918181019086841115615a6d575f80fd5b8286015b848110156150b75780516001600160401b0380821115615a8f575f80fd5b90880190601f196060838c0382011215615aa7575f80fd5b615aaf614e24565b8784015183811115615abf575f80fd5b8401610180818e0384011215615ad3575f80fd5b615adb614e46565b925088810151835260408101518984015260608101516040840152615b0260808201615933565b6060840152615b1360a082016153c7565b6080840152615b2460c082016153c7565b60a0840152615b3560e082016153c7565b60c0840152610100615b488183016153c7565b60e0850152610120808301518286015261014091508183015181860152506101608083015182860152610180830151915085821115615b85575f80fd5b615b938f8c84860101615641565b90850152505090815260408301519082821115615bae575f80fd5b615bbc8c8984870101615641565b8189015260609390930151604084015250508352918301918301615a71565b5f60a08284031215615beb575f80fd5b615bf3614dda565b9050615bfe826153c7565b81526020820151602082015260408201516001600160401b0380821115615c23575f80fd5b615c2f85838601615a30565b60408401526060840151915080821115615c47575f80fd5b615c5385838601615a30565b60608401526080840151915080821115615c6b575f80fd5b50615c7884828501615641565b60808301525092915050565b5f805f805f806101408789031215615c9a575f80fd5b8651615ca581614c09565b6020880151909650615cb681614c09565b60408801519095509350615ccd8860608901615874565b92506101008701516001600160401b0380821115615ce9575f80fd5b615cf58a838b0161593e565b9350610120890151915080821115615d0b575f80fd5b50615d1889828a01615bdb565b9150509295509295509295565b5f805f805f60a08688031215615d39575f80fd5b8551615d4481614c09565b6020870151909550615d5581614c09565b6040870151606088015191955093506001600160401b0380821115615d78575f80fd5b615d8489838a0161593e565b93506080880151915080821115615d99575f80fd5b50615da688828901615bdb565b915050929550929590935056fea2646970667358221220085d1f7160d4a46b24c9b59637c582033900fafc5866187ddd2e7ddf2e86c0d164736f6c63430008190033

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

00000000000000000000000078190e4c7c7b2c2c3b0562f1f155a1fc2f5160ca0000000000000000000000007d93fd973e203cda7a6479ba6a8dbdb2decde320000000000000000000000000888888888889758f76e7103c6cbf23abbf58f946000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000003ee118efc826d30a29645eaf3b2eaac9e8320185000000000000000000000000cdd26eb5eb2ce0f203a84553853667ae69ca29ce000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d2f13f7789f0000000000000000000000000000c917fba41b5247ef115d4490e9b50feb37e28cb7

-----Decoded View---------------
Arg [0] : _wiseLendingAddress (address): 0x78190e4c7C7B2c2C3b0562F1f155a1FC2F5160CA
Arg [1] : _pendleChildTokenAddress (address): 0x7D93Fd973E203cdA7a6479ba6A8DBdb2DecDE320
Arg [2] : _pendleRouter (address): 0x888888888889758F76e7103c6CbF23ABbF58F946
Arg [3] : _entryAsset (address): 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
Arg [4] : _pendleSy (address): 0x3Ee118EFC826d30A29645eAf3b2EaaC9E8320185
Arg [5] : _underlyingMarket (address): 0xcDd26Eb5EB2Ce0f203a84553853667aE69Ca29Ce
Arg [6] : _routerStatic (address): 0x0000000000000000000000000000000000000000
Arg [7] : _dexAddress (address): 0x0000000000000000000000000000000000000000
Arg [8] : _collateralFactor (uint256): 950000000000000000
Arg [9] : _powerFarmNFTs (address): 0xC917fbA41B5247eF115D4490E9b50fEB37E28Cb7

-----Encoded View---------------
10 Constructor Arguments found :
Arg [0] : 00000000000000000000000078190e4c7c7b2c2c3b0562f1f155a1fc2f5160ca
Arg [1] : 0000000000000000000000007d93fd973e203cda7a6479ba6a8dbdb2decde320
Arg [2] : 000000000000000000000000888888888889758f76e7103c6cbf23abbf58f946
Arg [3] : 000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Arg [4] : 0000000000000000000000003ee118efc826d30a29645eaf3b2eaac9e8320185
Arg [5] : 000000000000000000000000cdd26eb5eb2ce0f203a84553853667ae69ca29ce
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [8] : 0000000000000000000000000000000000000000000000000d2f13f7789f0000
Arg [9] : 000000000000000000000000c917fba41b5247ef115d4490e9b50feb37e28cb7


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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

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.