ETH Price: $2,590.00 (-3.86%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Withdraw196875032024-04-19 5:47:47298 days ago1713505667IN
0x3C8F64d5...8CF2CF99f
0 ETH0.0017216520.67083789
Remove Liquidity125781482021-06-06 2:11:321347 days ago1622945492IN
0x3C8F64d5...8CF2CF99f
0 ETH0.0012284111
Remove Liquidity125761932021-06-05 19:02:011347 days ago1622919721IN
0x3C8F64d5...8CF2CF99f
0 ETH0.0013400812
Remove Liquidity125758522021-06-05 17:46:051347 days ago1622915165IN
0x3C8F64d5...8CF2CF99f
0 ETH0.0013400812
Remove Liquidity125739462021-06-05 10:28:391347 days ago1622888919IN
0x3C8F64d5...8CF2CF99f
0 ETH0.0034780914.00000145
Remove Liquidity125734402021-06-05 8:37:351347 days ago1622882255IN
0x3C8F64d5...8CF2CF99f
0 ETH0.0028941714
Remove Liquidity125694082021-06-04 17:35:511348 days ago1622828151IN
0x3C8F64d5...8CF2CF99f
0 ETH0.0042485616
Remove Liquidity125668902021-06-04 8:32:551348 days ago1622795575IN
0x3C8F64d5...8CF2CF99f
0 ETH0.005310720
Get All Rewards125660632021-06-04 5:21:301348 days ago1622784090IN
0x3C8F64d5...8CF2CF99f
0 ETH0.0020735418.00000145
Get All Rewards125651592021-06-04 2:06:101349 days ago1622772370IN
0x3C8F64d5...8CF2CF99f
0 ETH0.0039689130
Remove Liquidity125645042021-06-03 23:36:021349 days ago1622763362IN
0x3C8F64d5...8CF2CF99f
0 ETH0.0082315831
Get All Rewards125333912021-05-30 3:46:311354 days ago1622346391IN
0x3C8F64d5...8CF2CF99f
0 ETH0.0025136419
Remove Liquidity125279252021-05-29 7:32:381354 days ago1622273558IN
0x3C8F64d5...8CF2CF99f
0 ETH0.0069406525
Remove Liquidity125126312021-05-26 22:29:581357 days ago1622068198IN
0x3C8F64d5...8CF2CF99f
0 ETH0.0100190134
Get All Rewards124052812021-05-10 7:22:431373 days ago1620631363IN
0x3C8F64d5...8CF2CF99f
0 ETH0.01364729102
Get All Rewards124036882021-05-10 1:38:341374 days ago1620610714IN
0x3C8F64d5...8CF2CF99f
0 ETH0.01539149102
Get All Rewards123553272021-05-02 14:35:031381 days ago1619966103IN
0x3C8F64d5...8CF2CF99f
0 ETH0.004979633
Remove Liquidity122280732021-04-12 22:50:161401 days ago1618267816IN
0x3C8F64d5...8CF2CF99f
0 ETH0.03240179122.1
Remove Liquidity122253742021-04-12 12:59:571401 days ago1618232397IN
0x3C8F64d5...8CF2CF99f
0 ETH0.0271959897
Remove Liquidity122253682021-04-12 12:58:341401 days ago1618232314IN
0x3C8F64d5...8CF2CF99f
0 ETH0.03142214104
Get All Rewards122253662021-04-12 12:57:501401 days ago1618232270IN
0x3C8F64d5...8CF2CF99f
0 ETH0.01415408104
Get All Rewards122235492021-04-12 6:12:431401 days ago1618207963IN
0x3C8F64d5...8CF2CF99f
0 ETH0.0075080162
Remove Liquidity121911952021-04-07 6:53:501406 days ago1617778430IN
0x3C8F64d5...8CF2CF99f
0 ETH0.03903798117
Get All Rewards121331962021-03-29 8:57:111415 days ago1617008231IN
0x3C8F64d5...8CF2CF99f
0 ETH0.01283628106
Remove Liquidity121150852021-03-26 14:09:351418 days ago1616767775IN
0x3C8F64d5...8CF2CF99f
0 ETH0.03426025116
View all transactions

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Block
From
To
119504852021-03-01 5:38:171443 days ago1614577097  Contract Creation0 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
StakePool

Compiler Version
v0.7.6+commit.7338295f

Optimization Enabled:
Yes with 999999 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-03-03
*/

/**
 *Submitted for verification at Etherscan.io on 2021-02-03
*/

// SPDX-License-Identifier: SEE LICENSE IN LICENSE

pragma solidity >=0.7.6;
pragma abicoder v2;

interface IStakePoolCreator {
    function version() external returns (uint256);

    function create() external returns (address);

    function initialize(
        address poolAddress,
        address pair,
        address rewardToken,
        address timelock,
        address stakePoolRewardFund,
        bytes calldata data
    ) external;
}

interface IValueLiquidRouter {
    struct Swap {
        address pool;
        address tokenIn;
        address tokenOut;
        uint256 swapAmount; // tokenInAmount / tokenOutAmount
        uint256 limitReturnAmount; // minAmountOut / maxAmountIn
        uint256 maxPrice;
        bool isBPool;
    }

    function factory() external view returns (address);

    function controller() external view returns (address);

    function formula() external view returns (address);

    function WETH() external view returns (address);

    function addLiquidity(
        address pair,
        address tokenA,
        address tokenB,
        uint256 amountADesired,
        uint256 amountBDesired,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    )
        external
        returns (
            uint256 amountA,
            uint256 amountB,
            uint256 liquidity
        );

    function addLiquidityETH(
        address pair,
        address token,
        uint256 amountTokenDesired,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    )
        external
        payable
        returns (
            uint256 amountToken,
            uint256 amountETH,
            uint256 liquidity
        );

    function swapExactTokensForTokens(
        address tokenIn,
        address tokenOut,
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline,
        uint8 flag
    ) external returns (uint256[] memory amounts);

    function swapTokensForExactTokens(
        address tokenIn,
        address tokenOut,
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline,
        uint8 flag
    ) external returns (uint256[] memory amounts);

    function swapExactETHForTokens(
        address tokenOut,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline,
        uint8 flag
    ) external payable returns (uint256[] memory amounts);

    function swapTokensForExactETH(
        address tokenIn,
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline,
        uint8 flag
    ) external returns (uint256[] memory amounts);

    function swapExactTokensForETH(
        address tokenIn,
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline,
        uint8 flag
    ) external returns (uint256[] memory amounts);

    function swapETHForExactTokens(
        address tokenOut,
        uint256 amountOut,
        address[] calldata path,
        address to,
        uint256 deadline,
        uint8 flag
    ) external payable returns (uint256[] memory amounts);

    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        address tokenIn,
        address tokenOut,
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline,
        uint8 flag
    ) external;

    function swapExactETHForTokensSupportingFeeOnTransferTokens(
        address tokenOut,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline,
        uint8 flag
    ) external payable;

    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        address tokenIn,
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline,
        uint8 flag
    ) external;

    function addStakeLiquidity(
        address stakePool,
        address tokenA,
        address tokenB,
        uint256 amountADesired,
        uint256 amountBDesired,
        uint256 amountAMin,
        uint256 amountBMin,
        uint256 deadline
    )
        external
        returns (
            uint256 amountA,
            uint256 amountB,
            uint256 liquidity
        );

    function addStakeLiquidityETH(
        address stakePool,
        address token,
        uint256 amountTokenDesired,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        uint256 deadline
    )
        external
        payable
        returns (
            uint256 amountToken,
            uint256 amountETH,
            uint256 liquidity
        );

    function multihopBatchSwapExactIn(
        Swap[][] memory swapSequences,
        address tokenIn,
        address tokenOut,
        uint256 totalAmountIn,
        uint256 minTotalAmountOut,
        uint256 deadline,
        uint8 flag
    ) external payable returns (uint256 totalAmountOut);

    function multihopBatchSwapExactOut(
        Swap[][] memory swapSequences,
        address tokenIn,
        address tokenOut,
        uint256 maxTotalAmountIn,
        uint256 deadline,
        uint8 flag
    ) external payable returns (uint256 totalAmountIn);

    function createPair(
        address tokenA,
        address tokenB,
        uint256 amountA,
        uint256 amountB,
        uint32 tokenWeightA,
        uint32 swapFee,
        address to,
        uint8 flag
    ) external returns (uint256 liquidity);

    function createPairETH(
        address token,
        uint256 amountToken,
        uint32 tokenWeight,
        uint32 swapFee,
        address to,
        uint8 flag
    ) external payable returns (uint256 liquidity);
}

interface IValueLiquidFactory {
    event PairCreated(address indexed token0, address indexed token1, address pair, uint32 tokenWeight0, uint32 swapFee, uint256);

    function feeTo() external view returns (address);

    function formula() external view returns (address);

    function protocolFee() external view returns (uint256);

    function feeToSetter() external view returns (address);

    function getPair(
        address tokenA,
        address tokenB,
        uint32 tokenWeightA,
        uint32 swapFee
    ) external view returns (address pair);

    function allPairs(uint256) external view returns (address pair);

    function isPair(address) external view returns (bool);

    function allPairsLength() external view returns (uint256);

    function createPair(
        address tokenA,
        address tokenB,
        uint32 tokenWeightA,
        uint32 swapFee
    ) external returns (address pair);

    function getWeightsAndSwapFee(address pair)
        external
        view
        returns (
            uint32 tokenWeight0,
            uint32 tokenWeight1,
            uint32 swapFee
        );

    function setFeeTo(address) external;

    function setFeeToSetter(address) external;

    function setProtocolFee(uint256) external;
}

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

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

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

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

interface IValueLiquidPair {
    event Approval(address indexed owner, address indexed spender, uint256 value);
    event Transfer(address indexed from, address indexed to, uint256 value);

    function name() external view returns (string memory);

    function symbol() external view returns (string memory);

    function decimals() external pure returns (uint8);

    function totalSupply() external view returns (uint256);

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

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

    function approve(address spender, uint256 value) external returns (bool);

    function transfer(address to, uint256 value) external returns (bool);

    function transferFrom(
        address from,
        address to,
        uint256 value
    ) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);

    function PERMIT_TYPEHASH() external pure returns (bytes32);

    function nonces(address owner) external view returns (uint256);

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

    event PaidProtocolFee(uint112 collectedFee0, uint112 collectedFee1);
    event Mint(address indexed sender, uint256 amount0, uint256 amount1);
    event Burn(address indexed sender, uint256 amount0, uint256 amount1, address indexed to);
    event Swap(address indexed sender, uint256 amount0In, uint256 amount1In, uint256 amount0Out, uint256 amount1Out, address indexed to);
    event Sync(uint112 reserve0, uint112 reserve1);

    function MINIMUM_LIQUIDITY() external pure returns (uint256);

    function factory() external view returns (address);

    function token0() external view returns (address);

    function token1() external view returns (address);

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

    function getCollectedFees() external view returns (uint112 _collectedFee0, uint112 _collectedFee1);

    function getTokenWeights() external view returns (uint32 tokenWeight0, uint32 tokenWeight1);

    function getSwapFee() external view returns (uint32);

    function price0CumulativeLast() external view returns (uint256);

    function price1CumulativeLast() external view returns (uint256);

    function mint(address to) external returns (uint256 liquidity);

    function burn(address to) external returns (uint256 amount0, uint256 amount1);

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

    function skim(address to) external;

    function sync() external;

    function initialize(
        address,
        address,
        uint32,
        uint32
    ) external;
}

// a library for performing overflow-safe math, courtesy of DappHub (https://github.com/dapphub/ds-math)
library SafeMath {
    function add(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require((z = x + y) >= x, "ds-math-add-overflow");
    }

    function sub(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require((z = x - y) <= x, "ds-math-sub-underflow");
    }

    function mul(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require(y == 0 || (z = x * y) / y == x, "ds-math-mul-overflow");
    }

    function div(uint256 a, uint256 b) internal pure returns (uint256 c) {
        require(b > 0, "ds-math-division-by-zero");
        c = a / b;
    }
}

contract TimeLock {
    using SafeMath for uint256;
    event NewAdmin(address indexed newAdmin);
    event NewPendingAdmin(address indexed newPendingAdmin);
    event NewDelay(uint256 indexed newDelay);
    event CancelTransaction(bytes32 indexed txHash, address indexed target, uint256 value, string signature, bytes data, uint256 eta);
    event ExecuteTransaction(bytes32 indexed txHash, address indexed target, uint256 value, string signature, bytes data, uint256 eta);
    event QueueTransaction(bytes32 indexed txHash, address indexed target, uint256 value, string signature, bytes data, uint256 eta);

    uint256 public constant GRACE_PERIOD = 14 days;
    uint256 public constant MINIMUM_DELAY = 1 days;
    uint256 public constant MAXIMUM_DELAY = 30 days;
    bool private _initialized;
    address public admin;
    address public pendingAdmin;
    uint256 public delay;
    bool public admin_initialized;
    mapping(bytes32 => bool) public queuedTransactions;

    constructor() {
        admin_initialized = false;
        _initialized = false;
    }

    function initialize(address _admin, uint256 _delay) public {
        require(_initialized == false, "Timelock::constructor: Initialized must be false.");
        require(_delay >= MINIMUM_DELAY, "Timelock::setDelay: Delay must exceed minimum delay.");
        require(_delay <= MAXIMUM_DELAY, "Timelock::setDelay: Delay must not exceed maximum delay.");
        delay = _delay;
        admin = _admin;
        _initialized = true;
        emit NewAdmin(admin);
        emit NewDelay(delay);
    }

    receive() external payable {}

    function setDelay(uint256 _delay) public {
        require(msg.sender == address(this), "Timelock::setDelay: Call must come from Timelock.");
        require(_delay >= MINIMUM_DELAY, "Timelock::setDelay: Delay must exceed minimum delay.");
        require(_delay <= MAXIMUM_DELAY, "Timelock::setDelay: Delay must not exceed maximum delay.");
        delay = _delay;
        emit NewDelay(delay);
    }

    function acceptAdmin() public {
        require(msg.sender == pendingAdmin, "Timelock::acceptAdmin: Call must come from pendingAdmin.");
        admin = msg.sender;
        pendingAdmin = address(0);
        emit NewAdmin(admin);
    }

    function setPendingAdmin(address _pendingAdmin) public {
        // allows one time setting of admin for deployment purposes
        if (admin_initialized) {
            require(msg.sender == address(this), "Timelock::setPendingAdmin: Call must come from Timelock.");
        } else {
            require(msg.sender == admin, "Timelock::setPendingAdmin: First call must come from admin.");
            admin_initialized = true;
        }
        pendingAdmin = _pendingAdmin;

        emit NewPendingAdmin(pendingAdmin);
    }

    function queueTransaction(
        address target,
        uint256 value,
        string memory signature,
        bytes memory data,
        uint256 eta
    ) public returns (bytes32) {
        require(msg.sender == admin, "Timelock::queueTransaction: Call must come from admin.");
        require(eta >= getBlockTimestamp().add(delay), "Timelock::queueTransaction: Estimated execution block must satisfy delay.");

        bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta));
        queuedTransactions[txHash] = true;

        emit QueueTransaction(txHash, target, value, signature, data, eta);
        return txHash;
    }

    function cancelTransaction(
        address target,
        uint256 value,
        string memory signature,
        bytes memory data,
        uint256 eta
    ) public {
        require(msg.sender == admin, "Timelock::cancelTransaction: Call must come from admin.");

        bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta));
        queuedTransactions[txHash] = false;

        emit CancelTransaction(txHash, target, value, signature, data, eta);
    }

    function executeTransaction(
        address target,
        uint256 value,
        string memory signature,
        bytes memory data,
        uint256 eta
    ) public payable returns (bytes memory) {
        require(msg.sender == admin, "Timelock::executeTransaction: Call must come from admin.");

        bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta));
        require(queuedTransactions[txHash], "Timelock::executeTransaction: Transaction hasn't been queued.");
        require(getBlockTimestamp() >= eta, "Timelock::executeTransaction: Transaction hasn't surpassed time lock.");
        require(getBlockTimestamp() <= eta.add(GRACE_PERIOD), "Timelock::executeTransaction: Transaction is stale.");

        queuedTransactions[txHash] = false;

        bytes memory callData;

        if (bytes(signature).length == 0) {
            callData = data;
        } else {
            callData = abi.encodePacked(bytes4(keccak256(bytes(signature))), data);
        }

        // solium-disable-next-line security/no-call-value
        (bool success, bytes memory returnData) = target.call{value: value}(callData);
        require(success, "Timelock::executeTransaction: Transaction execution reverted.");

        emit ExecuteTransaction(txHash, target, value, signature, data, eta);

        return returnData;
    }

    function getBlockTimestamp() internal view returns (uint256) {
        return block.timestamp;
    }
}

interface IStakePool {
    event Deposit(address indexed account, uint256 amount);
    event AddRewardPool(uint256 indexed poolId);
    event UpdateRewardPool(uint256 indexed poolId, uint256 endRewardBlock, uint256 rewardPerBlock);
    event PayRewardPool(
        uint256 indexed poolId,
        address indexed rewardToken,
        address indexed account,
        uint256 pendingReward,
        uint256 rebaseAmount,
        uint256 paidReward
    );
    event UpdateRewardRebaser(uint256 indexed poolId, address rewardRebaser);
    event UpdateRewardMultiplier(uint256 indexed poolId, address rewardMultiplier);
    event Withdraw(address indexed account, uint256 amount);

    function version() external view returns (uint256);

    function pair() external view returns (address);

    function initialize(
        address _pair,
        uint256 _unstakingFrozenTime,
        address _rewardFund,
        address _timelock
    ) external;

    function stake(uint256) external;

    function stakeFor(address _account) external;

    function withdraw(uint256) external;

    function getReward(uint8 _pid, address _account) external;

    function getAllRewards(address _account) external;

    function claimReward() external;

    function pendingReward(uint8 _pid, address _account) external view returns (uint256);

    function allowRecoverRewardToken(address _token) external view returns (bool);

    function getRewardPerBlock(uint8 pid) external view returns (uint256);

    function rewardPoolInfoLength() external view returns (uint256);

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

    function emergencyWithdraw() external;

    function updateReward() external;

    function updateReward(uint8 _pid) external;

    function updateRewardPool(
        uint8 _pid,
        uint256 _endRewardBlock,
        uint256 _rewardPerBlock
    ) external;

    function getRewardMultiplier(
        uint8 _pid,
        uint256 _from,
        uint256 _to,
        uint256 _rewardPerBlock
    ) external view returns (uint256);

    function getRewardRebase(
        uint8 _pid,
        address _rewardToken,
        uint256 _pendingReward
    ) external view returns (uint256);

    function updateRewardRebaser(uint8 _pid, address _rewardRebaser) external;

    function updateRewardMultiplier(uint8 _pid, address _rewardMultiplier) external;

    function getUserInfo(uint8 _pid, address _account)
        external
        view
        returns (
            uint256 amount,
            uint256 rewardDebt,
            uint256 accumulatedEarned,
            uint256 lockReward,
            uint256 lockRewardReleased
        );

    function addRewardPool(
        address _rewardToken,
        address _rewardRebaser,
        address _rewardMultiplier,
        uint256 _startBlock,
        uint256 _endRewardBlock,
        uint256 _rewardPerBlock,
        uint256 _lockRewardPercent,
        uint256 _startVestingBlock,
        uint256 _endVestingBlock
    ) external;

    function removeLiquidity(
        address provider,
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountA, uint256 amountB);

    function removeLiquidityETH(
        address provider,
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountToken, uint256 amountETH);

    function removeLiquidityETHSupportingFeeOnTransferTokens(
        address provider,
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountETH);
}

interface IValueLiquidProvider {
    function factory() external view returns (address);

    function controller() external view returns (address);

    function formula() external view returns (address);

    function WETH() external view returns (address);

    function removeLiquidity(
        address pair,
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountA, uint256 amountB);

    function removeLiquidityETH(
        address pair,
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountToken, uint256 amountETH);

    function removeLiquidityWithPermit(
        address pair,
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountA, uint256 amountB);

    function removeLiquidityETHWithPermit(
        address pair,
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountToken, uint256 amountETH);

    function removeLiquidityETHSupportingFeeOnTransferTokens(
        address pair,
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountETH);

    function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
        address pair,
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountETH);

    function stake(
        address stakePool,
        uint256 amount,
        uint256 deadline
    ) external;

    function stakeWithPermit(
        address stakePool,
        uint256 amount,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;
}

interface IStakePoolController {
    event MasterCreated(address indexed farm, address indexed pair, uint256 version, address timelock, address stakePoolRewardFund, uint256 totalStakePool);
    event SetWhitelistStakingFor(address indexed contractAddress, bool value);
    event SetWhitelistStakePool(address indexed contractAddress, int8 value);
    event SetStakePoolCreator(address indexed contractAddress, uint256 verion);
    event SetWhitelistRewardRebaser(address indexed contractAddress, bool value);
    event SetWhitelistRewardMultiplier(address indexed contractAddress, bool value);
    event SetStakePoolVerifier(address indexed contractAddress, bool value);
    event ChangeGovernance(address indexed governance);
    event SetFeeCollector(address indexed feeCollector);
    event SetFeeToken(address indexed token);
    event SetFeeAmount(uint256 indexed amount);

    function allStakePools(uint256) external view returns (address stakePool);

    function isStakePool(address contractAddress) external view returns (bool);

    function isStakePoolVerifier(address contractAddress) external view returns (bool);

    function isWhitelistStakingFor(address contractAddress) external view returns (bool);

    function isWhitelistStakePool(address contractAddress) external view returns (int8);

    function setStakePoolVerifier(address contractAddress, bool state) external;

    function setWhitelistStakingFor(address contractAddress, bool state) external;

    function setWhitelistStakePool(address contractAddress, int8 state) external;

    function addStakePoolCreator(address contractAddress) external;

    function isWhitelistRewardRebaser(address contractAddress) external view returns (bool);

    function isAllowEmergencyWithdrawStakePool(address _address) external view returns (bool);

    function setWhitelistRewardRebaser(address contractAddress, bool state) external;

    function isWhitelistRewardMultiplier(address contractAddress) external view returns (bool);

    function setAllowEmergencyWithdrawStakePool(address _address, bool state) external;

    function setWhitelistRewardMultiplier(address contractAddress, bool state) external;

    function setEnableWhitelistRewardRebaser(bool value) external;

    function setEnableWhitelistRewardMultiplier(bool value) external;

    function allStakePoolsLength() external view returns (uint256);

    function create(
        uint256 version,
        address pair,
        address rewardToken,
        uint256 rewardFundAmount,
        uint256 delayTimeLock,
        bytes calldata data,
        uint8 flag
    ) external returns (address);

    function createPair(
        uint256 version,
        address tokenA,
        address tokenB,
        uint32 tokenWeightA,
        uint32 swapFee,
        address rewardToken,
        uint256 rewardFundAmount,
        uint256 delayTimeLock,
        bytes calldata poolRewardInfo,
        uint8 flag
    ) external returns (address);

    function setGovernance(address) external;

    function setFeeCollector(address _address) external;

    function setFeeToken(address _token) external;

    function setFeeAmount(uint256 _token) external;
}

interface IStakePoolRewardRebaser {
    function getRebaseAmount(address rewardToken, uint256 baseAmount) external view returns (uint256);
}

interface IStakePoolRewardMultiplier {
    function getRewardMultiplier(
        uint256 _start,
        uint256 _end,
        uint256 _from,
        uint256 _to,
        uint256 _rewardPerBlock
    ) external view returns (uint256);
}

interface IERC20 {
    event Approval(address indexed owner, address indexed spender, uint256 value);
    event Transfer(address indexed from, address indexed to, uint256 value);

    function name() external view returns (string memory);

    function symbol() external view returns (string memory);

    function decimals() external view returns (uint8);

    function totalSupply() external view returns (uint256);

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

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

    function approve(address spender, uint256 value) external returns (bool);

    function transfer(address to, uint256 value) external returns (bool);

    function transferFrom(
        address from,
        address to,
        uint256 value
    ) external returns (bool);
}

interface IStakePoolRewardFund {
    function initialize(address _stakePool, address _timelock) external;

    function safeTransfer(
        address _token,
        address _to,
        uint256 _value
    ) external;
}

// This implements BPool contract, and allows for generalized staking, yield farming, and token distribution.
contract StakePool is IStakePool {
    using SafeMath for uint256;
    uint256 public override version;
    // Info of each user.
    struct UserInfo {
        uint256 amount;
        mapping(uint8 => uint256) rewardDebt;
        mapping(uint8 => uint256) reward;
        mapping(uint8 => uint256) accumulatedEarned; // will accumulate every time user harvest
        mapping(uint8 => uint256) lockReward;
        mapping(uint8 => uint256) lockRewardReleased;
        uint256 lastStakeTime;
    }

    // Info of each rewardPool funding.
    struct RewardPoolInfo {
        address rewardToken; // Address of rewardPool token contract.
        address rewardRebaser; // Address of rewardRebaser contract.
        address rewardMultiplier; // Address of rewardMultiplier contract.
        uint256 startRewardBlock; // Start reward block number that rewardPool distribution occurs.
        uint256 lastRewardBlock; // Last block number that rewardPool distribution occurs.
        uint256 endRewardBlock; // Block number which rewardPool distribution ends.
        uint256 rewardPerBlock; // Reward token amount to distribute per block.
        uint256 accRewardPerShare; // Accumulated rewardPool per share, times 1e18.
        uint256 lockRewardPercent; // Lock reward percent - 0 to disable lock & vesting
        uint256 startVestingBlock; // Block number which vesting starts.
        uint256 endVestingBlock; // Block number which vesting ends.
        uint256 numOfVestingBlocks;
        uint256 totalPaidRewards;
    }

    mapping(address => UserInfo) public userInfo;
    RewardPoolInfo[] public rewardPoolInfo;
    address public override pair;
    address public rewardFund;
    address public timelock;
    address public controller;

    uint256 public balance;
    uint256 public unstakingFrozenTime = 3 days;
    uint256 private unlocked = 1;
    bool private _initialized = false;
    uint256 public constant BLOCKS_PER_DAY = 6528;

    constructor(address _controller, uint256 _version) {
        controller = _controller;
        timelock = msg.sender;
        version = _version;
    }

    modifier lock() {
        require(unlocked == 1, "StakePool: LOCKED");
        unlocked = 0;
        _;
        unlocked = 1;
    }
    modifier onlyTimeLock() {
        require(msg.sender == timelock, "StakePool: !timelock");
        _;
    }

    function allowRecoverRewardToken(address _token) external view override returns (bool) {
        for (uint8 pid = 0; pid < rewardPoolInfo.length; ++pid) {
            RewardPoolInfo storage rewardPool = rewardPoolInfo[pid];
            if (rewardPool.rewardToken == _token) {
                // do not allow to drain reward token if less than 30 days after pool ends
                if (block.number < (rewardPool.endRewardBlock + (BLOCKS_PER_DAY * 30))) {
                    return false;
                }
            }
        }
        return true;
    }

    // called once by the factory at time of deployment
    function initialize(
        address _pair,
        uint256 _unstakingFrozenTime,
        address _rewardFund,
        address _timelock
    ) external override {
        require(_initialized == false, "StakePool: Initialize must be false.");
        require(unstakingFrozenTime <= 30 days, "StakePool: unstakingFrozenTime > 30 days");
        pair = _pair;
        unstakingFrozenTime = _unstakingFrozenTime;
        rewardFund = _rewardFund;
        timelock = _timelock;
        _initialized = true;
    }

    function addRewardPool(
        address _rewardToken,
        address _rewardRebaser,
        address _rewardMultiplier,
        uint256 _startBlock,
        uint256 _endRewardBlock,
        uint256 _rewardPerBlock,
        uint256 _lockRewardPercent,
        uint256 _startVestingBlock,
        uint256 _endVestingBlock
    ) external override lock onlyTimeLock {
        require(rewardPoolInfo.length <= 16, "StakePool: Reward pool length > 16");
        require(IStakePoolController(controller).isWhitelistRewardRebaser(_rewardRebaser), "StakePool: Invalid reward rebaser");
        require(IStakePoolController(controller).isWhitelistRewardMultiplier(_rewardMultiplier), "StakePool: Invalid reward multiplier");
        require(_startVestingBlock <= _endVestingBlock, "StakePool: startVestingBlock > endVestingBlock");
        _startBlock = (block.number > _startBlock) ? block.number : _startBlock;
        require(_startBlock < _endRewardBlock, "StakePool: startBlock >= endRewardBlock");
        require(_lockRewardPercent <= 100, "StakePool: invalid lockRewardPercent");
        updateReward();
        rewardPoolInfo.push(
            RewardPoolInfo({
                rewardToken: _rewardToken,
                rewardRebaser: _rewardRebaser,
                startRewardBlock: _startBlock,
                rewardMultiplier: _rewardMultiplier,
                lastRewardBlock: _startBlock,
                endRewardBlock: _endRewardBlock,
                rewardPerBlock: _rewardPerBlock,
                accRewardPerShare: 0,
                lockRewardPercent: _lockRewardPercent,
                startVestingBlock: _startVestingBlock,
                endVestingBlock: _endVestingBlock,
                numOfVestingBlocks: _endVestingBlock - _startVestingBlock,
                totalPaidRewards: 0
            })
        );
        emit AddRewardPool(rewardPoolInfo.length - 1);
    }

    function updateRewardMultiplier(uint8 _pid, address _rewardMultiplier) external override lock onlyTimeLock {
        require(IStakePoolController(controller).isWhitelistRewardMultiplier(_rewardMultiplier), "StakePool: Invalid reward multiplier");
        updateReward(_pid);
        RewardPoolInfo storage rewardPool = rewardPoolInfo[_pid];
        rewardPool.rewardMultiplier = _rewardMultiplier;
        emit UpdateRewardMultiplier(_pid, _rewardMultiplier);
    }

    function updateRewardRebaser(uint8 _pid, address _rewardRebaser) external override lock onlyTimeLock {
        require(IStakePoolController(controller).isWhitelistRewardRebaser(_rewardRebaser), "StakePool: Invalid reward rebaser");
        updateReward(_pid);
        RewardPoolInfo storage rewardPool = rewardPoolInfo[_pid];
        rewardPool.rewardRebaser = _rewardRebaser;
        emit UpdateRewardRebaser(_pid, _rewardRebaser);
    }

    // Return reward multiplier over the given _from to _to block.
    function getRewardMultiplier(
        uint8 _pid,
        uint256 _from,
        uint256 _to,
        uint256 _rewardPerBlock
    ) public view override returns (uint256) {
        RewardPoolInfo storage rewardPool = rewardPoolInfo[_pid];
        address rewardMultiplier = rewardPool.rewardMultiplier;
        if (rewardMultiplier == address(0)) {
            return _to.sub(_from).mul(_rewardPerBlock);
        }
        return
            IStakePoolRewardMultiplier(rewardMultiplier).getRewardMultiplier(
                rewardPool.startRewardBlock,
                rewardPool.endRewardBlock,
                _from,
                _to,
                _rewardPerBlock
            );
    }

    function getRewardRebase(
        uint8 _pid,
        address _rewardToken,
        uint256 _pendingReward
    ) public view override returns (uint256) {
        RewardPoolInfo storage rewardPool = rewardPoolInfo[_pid];
        address rewardRebaser = rewardPool.rewardRebaser;
        if (rewardRebaser == address(0)) {
            return _pendingReward;
        }
        return IStakePoolRewardRebaser(rewardRebaser).getRebaseAmount(_rewardToken, _pendingReward);
    }

    function getRewardPerBlock(uint8 pid) external view override returns (uint256) {
        RewardPoolInfo storage rewardPool = rewardPoolInfo[pid];
        uint256 rewardPerBlock = rewardPool.rewardPerBlock;
        if (block.number < rewardPool.startRewardBlock || block.number > rewardPool.endRewardBlock) return 0;
        uint256 reward = getRewardMultiplier(pid, block.number, block.number + 1, rewardPerBlock);
        return getRewardRebase(pid, rewardPool.rewardToken, reward);
    }

    function updateRewardPool(
        uint8 _pid,
        uint256 _endRewardBlock,
        uint256 _rewardPerBlock
    ) external override lock onlyTimeLock {
        RewardPoolInfo storage rewardPool = rewardPoolInfo[_pid];
        require(block.number <= rewardPool.endRewardBlock && block.number <= _endRewardBlock, "StakePool: blockNumber > endRewardBlock");
        updateReward(_pid);
        rewardPool.endRewardBlock = _endRewardBlock;
        rewardPool.rewardPerBlock = _rewardPerBlock;
        emit UpdateRewardPool(_pid, _endRewardBlock, _rewardPerBlock);
    }

    function stake(uint256 _amount) external override lock {
        IValueLiquidPair(pair).transferFrom(msg.sender, address(this), _amount);
        _stakeFor(msg.sender);
    }

    function stakeFor(address _account) external override lock {
        require(IStakePoolController(controller).isWhitelistStakingFor(msg.sender), "StakePool: Invalid sender");
        _stakeFor(_account);
    }

    function _stakeFor(address _account) internal {
        uint256 _amount = IValueLiquidPair(pair).balanceOf(address(this)).sub(balance);
        require(_amount > 0, "StakePool: Invalid balance");
        balance = balance.add(_amount);
        UserInfo storage user = userInfo[_account];
        getAllRewards(_account);
        user.amount = user.amount.add(_amount);
        uint8 rewardPoolLength = uint8(rewardPoolInfo.length);
        for (uint8 _pid = 0; _pid < rewardPoolLength; ++_pid) {
            user.rewardDebt[_pid] = user.amount.mul(rewardPoolInfo[_pid].accRewardPerShare).div(1e18);
        }
        user.lastStakeTime = block.timestamp;
        emit Deposit(_account, _amount);
    }

    function rewardPoolInfoLength() public view override returns (uint256) {
        return rewardPoolInfo.length;
    }

    function unfrozenStakeTime(address _account) public view override returns (uint256) {
        return userInfo[_account].lastStakeTime + unstakingFrozenTime;
    }

    function removeStakeInternal(uint256 _amount) internal {
        UserInfo storage user = userInfo[msg.sender];
        require(user.amount >= _amount, "StakePool: invalid withdraw amount");
        require(block.timestamp >= user.lastStakeTime.add(unstakingFrozenTime), "StakePool: frozen");
        getAllRewards(msg.sender);
        balance = balance.sub(_amount);
        user.amount = user.amount.sub(_amount);
        uint8 rewardPoolLength = uint8(rewardPoolInfo.length);
        for (uint8 _pid = 0; _pid < rewardPoolLength; ++_pid) {
            user.rewardDebt[_pid] = user.amount.mul(rewardPoolInfo[_pid].accRewardPerShare).div(1e18);
        }
    }

    function withdraw(uint256 _amount) external override lock {
        removeStakeInternal(_amount);
        IValueLiquidPair(pair).transfer(msg.sender, _amount);
        emit Withdraw(msg.sender, _amount);
    }

    function getAllRewards(address _account) public override {
        uint8 rewardPoolLength = uint8(rewardPoolInfo.length);
        for (uint8 _pid = 0; _pid < rewardPoolLength; ++_pid) {
            getReward(_pid, _account);
        }
    }

    function claimReward() external override {
        getAllRewards(msg.sender);
    }

    function getReward(uint8 _pid, address _account) public override {
        updateReward(_pid);
        UserInfo storage user = userInfo[_account];
        RewardPoolInfo storage rewardPool = rewardPoolInfo[_pid];
        uint256 _accRewardPerShare = rewardPool.accRewardPerShare;
        uint256 _pendingReward = user.amount.mul(_accRewardPerShare).div(1e18).sub(user.rewardDebt[_pid]);
        uint256 _lockRewardPercent = rewardPool.lockRewardPercent;
        if (_lockRewardPercent > 0) {
            if (block.number > rewardPool.endVestingBlock) {
                uint256 _unlockReward = user.lockReward[_pid].sub(user.lockRewardReleased[_pid]);
                if (_unlockReward > 0) {
                    _pendingReward = _pendingReward.add(_unlockReward);
                    user.lockRewardReleased[_pid] = user.lockRewardReleased[_pid].add(_unlockReward);
                }
            } else {
                if (_pendingReward > 0) {
                    uint256 _toLocked = _pendingReward.mul(_lockRewardPercent).div(100);
                    _pendingReward = _pendingReward.sub(_toLocked);
                    user.lockReward[_pid] = user.lockReward[_pid].add(_toLocked);
                }
                uint256 _startVestingBlock = rewardPool.startVestingBlock;
                if (block.number > _startVestingBlock) {
                    uint256 _toReleased = user.lockReward[_pid].mul(block.number.sub(_startVestingBlock)).div(rewardPool.numOfVestingBlocks);
                    uint256 _lockRewardReleased = user.lockRewardReleased[_pid];
                    if (_toReleased > _lockRewardReleased) {
                        uint256 _unlockReward = _toReleased.sub(_lockRewardReleased);
                        user.lockRewardReleased[_pid] = _lockRewardReleased.add(_unlockReward);
                        _pendingReward = _pendingReward.add(_unlockReward);
                    }
                }
            }
        }
        if (_pendingReward > 0) {
            user.accumulatedEarned[_pid] = user.accumulatedEarned[_pid].add(_pendingReward);
            rewardPool.totalPaidRewards = rewardPool.totalPaidRewards.add(_pendingReward);
            user.rewardDebt[_pid] = user.amount.mul(_accRewardPerShare).div(1e18);
            uint256 reward = user.reward[_pid].add(_pendingReward);
            user.reward[_pid] = reward;
            // Safe reward transfer, just in case if rounding error causes pool to not have enough reward amount
            address rewardToken = rewardPool.rewardToken;
            uint256 rewardBalance = IERC20(rewardToken).balanceOf(rewardFund);
            if (rewardBalance > 0) {
                user.reward[_pid] = 0;
                uint256 rebaseAmount = getRewardRebase(_pid, rewardToken, reward);
                uint256 paidAmount = rebaseAmount > rewardBalance ? rewardBalance : rebaseAmount;
                IStakePoolRewardFund(rewardFund).safeTransfer(rewardToken, _account, paidAmount);
                emit PayRewardPool(_pid, rewardToken, _account, reward, rebaseAmount, paidAmount);
            }
        }
    }

    function pendingReward(uint8 _pid, address _account) external view override returns (uint256) {
        UserInfo storage user = userInfo[_account];
        RewardPoolInfo storage rewardPool = rewardPoolInfo[_pid];
        uint256 _accRewardPerShare = rewardPool.accRewardPerShare;
        uint256 lpSupply = IValueLiquidPair(pair).balanceOf(address(this));
        uint256 _endRewardBlock = rewardPool.endRewardBlock;
        uint256 _endRewardBlockApplicable = block.number > _endRewardBlock ? _endRewardBlock : block.number;
        uint256 _lastRewardBlock = rewardPool.lastRewardBlock;
        if (_endRewardBlockApplicable > _lastRewardBlock && lpSupply != 0) {
            uint256 _incRewardPerShare =
                getRewardMultiplier(_pid, _lastRewardBlock, _endRewardBlockApplicable, rewardPool.rewardPerBlock).mul(1e18).div(lpSupply);
            _accRewardPerShare = _accRewardPerShare.add(_incRewardPerShare);
        }
        uint256 pending = user.amount.mul(_accRewardPerShare).div(1e18).add(user.reward[_pid]).sub(user.rewardDebt[_pid]);
        return getRewardRebase(_pid, rewardPool.rewardToken, pending);
    }

    // Withdraw without caring about rewards. EMERGENCY ONLY.
    function emergencyWithdraw() external override lock {
        require(IStakePoolController(controller).isAllowEmergencyWithdrawStakePool(address(this)), "StakePool: Not allow emergencyWithdraw");
        UserInfo storage user = userInfo[msg.sender];
        uint256 amount = user.amount;
        balance = balance.sub(amount);
        user.amount = 0;
        IValueLiquidPair(pair).transfer(msg.sender, amount);
        uint8 rewardPoolLength = uint8(rewardPoolInfo.length);
        for (uint8 _pid = 0; _pid < rewardPoolLength; ++_pid) {
            user.rewardDebt[_pid] = 0;
            user.reward[_pid] = 0;
        }
    }

    function getUserInfo(uint8 _pid, address _account)
        public
        view
        override
        returns (
            uint256 amount,
            uint256 rewardDebt,
            uint256 accumulatedEarned,
            uint256 lockReward,
            uint256 lockRewardReleased
        )
    {
        UserInfo storage user = userInfo[_account];
        amount = user.amount;
        rewardDebt = user.rewardDebt[_pid];
        accumulatedEarned = user.accumulatedEarned[_pid];
        lockReward = user.lockReward[_pid];
        lockRewardReleased = user.lockRewardReleased[_pid];
    }

    function updateReward() public override {
        uint8 rewardPoolLength = uint8(rewardPoolInfo.length);
        for (uint8 _pid = 0; _pid < rewardPoolLength; ++_pid) {
            updateReward(_pid);
        }
    }

    function updateReward(uint8 _pid) public override {
        RewardPoolInfo storage rewardPool = rewardPoolInfo[_pid];
        uint256 _endRewardBlock = rewardPool.endRewardBlock;
        uint256 _endRewardBlockApplicable = block.number > _endRewardBlock ? _endRewardBlock : block.number;
        uint256 _lastRewardBlock = rewardPool.lastRewardBlock;
        if (_endRewardBlockApplicable > _lastRewardBlock) {
            uint256 lpSupply = IValueLiquidPair(pair).balanceOf(address(this));
            if (lpSupply > 0) {
                uint256 _incRewardPerShare =
                    getRewardMultiplier(_pid, _lastRewardBlock, _endRewardBlockApplicable, rewardPool.rewardPerBlock).mul(1e18).div(lpSupply);
                rewardPool.accRewardPerShare = rewardPool.accRewardPerShare.add(_incRewardPerShare);
            }
            rewardPool.lastRewardBlock = _endRewardBlockApplicable;
        }
    }

    function removeLiquidity(
        address provider,
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    ) public override lock returns (uint256 amountA, uint256 amountB) {
        require(IStakePoolController(controller).isWhitelistStakingFor(provider), "StakePool: Invalid provider");
        removeStakeInternal(liquidity);
        IValueLiquidPair(pair).approve(provider, liquidity);
        emit Withdraw(msg.sender, liquidity);
        (amountA, amountB) = IValueLiquidProvider(provider).removeLiquidity(address(pair), tokenA, tokenB, liquidity, amountAMin, amountBMin, to, deadline);
    }

    function removeLiquidityETH(
        address provider,
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) external override lock returns (uint256 amountToken, uint256 amountETH) {
        require(IStakePoolController(controller).isWhitelistStakingFor(provider), "StakePool: Invalid provider");
        removeStakeInternal(liquidity);
        IValueLiquidPair(pair).approve(provider, liquidity);
        emit Withdraw(msg.sender, liquidity);
        (amountToken, amountETH) = IValueLiquidProvider(provider).removeLiquidityETH(
            address(pair),
            token,
            liquidity,
            amountTokenMin,
            amountETHMin,
            to,
            deadline
        );
    }

    function removeLiquidityETHSupportingFeeOnTransferTokens(
        address provider,
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) external override lock returns (uint256 amountETH) {
        require(IStakePoolController(controller).isWhitelistStakingFor(provider), "StakePool: Invalid provider");
        removeStakeInternal(liquidity);
        IValueLiquidPair(pair).approve(provider, liquidity);
        emit Withdraw(msg.sender, liquidity);
        amountETH = IValueLiquidProvider(provider).removeLiquidityETHSupportingFeeOnTransferTokens(
            address(pair),
            token,
            liquidity,
            amountTokenMin,
            amountETHMin,
            to,
            deadline
        );
    }
}

contract StakePoolCreator is IStakePoolCreator {
    uint256 public override version = 3001;

    struct PoolRewardInfo {
        address rewardRebaser;
        address rewardMultiplier;
        uint256 startBlock;
        uint256 endRewardBlock;
        uint256 rewardPerBlock;
        uint256 lockRewardPercent;
        uint256 startVestingBlock;
        uint256 endVestingBlock;
        uint256 unstakingFrozenTime;
    }

    function create() external override returns (address) {
        StakePool pool = new StakePool(msg.sender, version);
        return address(pool);
    }

    function initialize(
        address poolAddress,
        address pair,
        address rewardToken,
        address timelock,
        address stakePoolRewardFund,
        bytes calldata data
    ) external override {
        StakePool pool = StakePool(poolAddress);
        PoolRewardInfo memory poolRewardInfo = abi.decode(data, (PoolRewardInfo));
        pool.addRewardPool(
            rewardToken,
            poolRewardInfo.rewardRebaser,
            poolRewardInfo.rewardMultiplier,
            poolRewardInfo.startBlock,
            poolRewardInfo.endRewardBlock,
            poolRewardInfo.rewardPerBlock,
            poolRewardInfo.lockRewardPercent,
            poolRewardInfo.startVestingBlock,
            poolRewardInfo.endVestingBlock
        );
        pool.initialize(pair, poolRewardInfo.unstakingFrozenTime, address(stakePoolRewardFund), address(timelock));
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_controller","type":"address"},{"internalType":"uint256","name":"_version","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"poolId","type":"uint256"}],"name":"AddRewardPool","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"poolId","type":"uint256"},{"indexed":true,"internalType":"address","name":"rewardToken","type":"address"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"pendingReward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rebaseAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"paidReward","type":"uint256"}],"name":"PayRewardPool","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"poolId","type":"uint256"},{"indexed":false,"internalType":"address","name":"rewardMultiplier","type":"address"}],"name":"UpdateRewardMultiplier","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"poolId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endRewardBlock","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rewardPerBlock","type":"uint256"}],"name":"UpdateRewardPool","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"poolId","type":"uint256"},{"indexed":false,"internalType":"address","name":"rewardRebaser","type":"address"}],"name":"UpdateRewardRebaser","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"BLOCKS_PER_DAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardToken","type":"address"},{"internalType":"address","name":"_rewardRebaser","type":"address"},{"internalType":"address","name":"_rewardMultiplier","type":"address"},{"internalType":"uint256","name":"_startBlock","type":"uint256"},{"internalType":"uint256","name":"_endRewardBlock","type":"uint256"},{"internalType":"uint256","name":"_rewardPerBlock","type":"uint256"},{"internalType":"uint256","name":"_lockRewardPercent","type":"uint256"},{"internalType":"uint256","name":"_startVestingBlock","type":"uint256"},{"internalType":"uint256","name":"_endVestingBlock","type":"uint256"}],"name":"addRewardPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"allowRecoverRewardToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"balance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"controller","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getAllRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_pid","type":"uint8"},{"internalType":"address","name":"_account","type":"address"}],"name":"getReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_pid","type":"uint8"},{"internalType":"uint256","name":"_from","type":"uint256"},{"internalType":"uint256","name":"_to","type":"uint256"},{"internalType":"uint256","name":"_rewardPerBlock","type":"uint256"}],"name":"getRewardMultiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"pid","type":"uint8"}],"name":"getRewardPerBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"_pid","type":"uint8"},{"internalType":"address","name":"_rewardToken","type":"address"},{"internalType":"uint256","name":"_pendingReward","type":"uint256"}],"name":"getRewardRebase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"_pid","type":"uint8"},{"internalType":"address","name":"_account","type":"address"}],"name":"getUserInfo","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"rewardDebt","type":"uint256"},{"internalType":"uint256","name":"accumulatedEarned","type":"uint256"},{"internalType":"uint256","name":"lockReward","type":"uint256"},{"internalType":"uint256","name":"lockRewardReleased","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_pair","type":"address"},{"internalType":"uint256","name":"_unstakingFrozenTime","type":"uint256"},{"internalType":"address","name":"_rewardFund","type":"address"},{"internalType":"address","name":"_timelock","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"_pid","type":"uint8"},{"internalType":"address","name":"_account","type":"address"}],"name":"pendingReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"provider","type":"address"},{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"provider","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"provider","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityETHSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardFund","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardPoolInfo","outputs":[{"internalType":"address","name":"rewardToken","type":"address"},{"internalType":"address","name":"rewardRebaser","type":"address"},{"internalType":"address","name":"rewardMultiplier","type":"address"},{"internalType":"uint256","name":"startRewardBlock","type":"uint256"},{"internalType":"uint256","name":"lastRewardBlock","type":"uint256"},{"internalType":"uint256","name":"endRewardBlock","type":"uint256"},{"internalType":"uint256","name":"rewardPerBlock","type":"uint256"},{"internalType":"uint256","name":"accRewardPerShare","type":"uint256"},{"internalType":"uint256","name":"lockRewardPercent","type":"uint256"},{"internalType":"uint256","name":"startVestingBlock","type":"uint256"},{"internalType":"uint256","name":"endVestingBlock","type":"uint256"},{"internalType":"uint256","name":"numOfVestingBlocks","type":"uint256"},{"internalType":"uint256","name":"totalPaidRewards","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardPoolInfoLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"stakeFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"timelock","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"unfrozenStakeTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unstakingFrozenTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"_pid","type":"uint8"}],"name":"updateReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updateReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_pid","type":"uint8"},{"internalType":"address","name":"_rewardMultiplier","type":"address"}],"name":"updateRewardMultiplier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_pid","type":"uint8"},{"internalType":"uint256","name":"_endRewardBlock","type":"uint256"},{"internalType":"uint256","name":"_rewardPerBlock","type":"uint256"}],"name":"updateRewardPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_pid","type":"uint8"},{"internalType":"address","name":"_rewardRebaser","type":"address"}],"name":"updateRewardRebaser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userInfo","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"lastStakeTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526203f4806008556001600955600a805460ff191690553480156200002757600080fd5b5060405162003d8038038062003d808339810160408190526200004a916200007d565b600680546001600160a01b039093166001600160a01b0319938416179055600580549092163317909155600055620000b7565b6000806040838503121562000090578182fd5b82516001600160a01b0381168114620000a7578283fd5b6020939093015192949293505050565b613cb980620000c76000396000f3fe608060405234801561001057600080fd5b50600436106102415760003560e01c806385cc179e11610145578063c0eac9ea116100bd578063e2589d381161008c578063efe2226611610071578063efe22266146104ad578063f36c0a72146104b5578063f77c4791146104bd57610241565b8063e2589d3814610487578063ebb5d2e91461049a57610241565b8063c0eac9ea14610451578063d33219b414610464578063db2e21bc1461046c578063e1f4a7841461047457610241565b8063b56b681d11610114578063b88a802f116100f9578063b88a802f14610423578063be6153351461042b578063c012c42e1461043e57610241565b8063b56b681d14610408578063b69ef8a81461041b57610241565b806385cc179e146103ba57806393ae1d1f146103cd578063a694fc3a146103e0578063a8aa1b31146103f357610241565b80634bf69206116101d85780636bb987fe116101a757806372aa0a601161018c57806372aa0a601461036857806376d743fe146103945780638583f6a5146103a757610241565b80636bb987fe1461034d5780636d3c6d921461035557610241565b80634bf692061461030c57806354fd4d501461031f578063597293f31461032757806360d470881461033a57610241565b80633468a5b8116102145780633468a5b8146102be578063358394d8146102de578063362a3fad146102f1578063437686491461030457610241565b806317837baa146102465780631959a0021461026457806329d79588146102855780632e1a7d4d146102a9575b600080fd5b61024e6104c5565b60405161025b9190613c33565b60405180910390f35b610277610272366004613146565b6104cb565b60405161025b929190613c3c565b610298610293366004613396565b6104e4565b60405161025b959493929190613c60565b6102bc6102b7366004613329565b610544565b005b6102d16102cc366004613146565b610698565b60405161025b9190613603565b6102bc6102ec3660046132bd565b610720565b6102bc6102ff366004613146565b610831565b61024e61085c565b6102bc61031a366004613146565b610862565b61024e610990565b61024e6103353660046133c8565b610996565b61024e610348366004613146565b610a96565b61024e610ac8565b6102bc610363366004613396565b610ace565b61037b610376366004613329565b610fa3565b60405161025b9d9c9b9a9998979695949392919061353b565b6102bc6103a2366004613403565b611036565b6102bc6103b5366004613396565b611195565b6102bc6103c836600461337c565b6113ba565b61024e6103db36600461337c565b611506565b6102bc6103ee366004613329565b611598565b6103fb61168f565b60405161025b919061346d565b610277610416366004613254565b6116ab565b61024e611997565b6102bc61199d565b61024e610439366004613396565b6119a8565b61024e61044c366004613435565b611b8b565b6102bc61045f3660046131da565b611ca3565b6103fb61223f565b6102bc61225b565b610277610482366004613160565b612495565b6102bc610495366004613396565b612784565b61024e6104a8366004613254565b612997565b6103fb612c7f565b6102bc612c9b565b6103fb612cc4565b60085481565b6001602052600090815260409020805460069091015482565b73ffffffffffffffffffffffffffffffffffffffff166000908152600160208181526040808420805460ff909616855292830182528084205460038401835281852054600485018452828620546005909501909352932054939492939092565b600954600114610589576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613895565b60405180910390fd5b600060095561059781612ce0565b6003546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063a9059cbb906105ef90339085906004016134bf565b602060405180830381600087803b15801561060957600080fd5b505af115801561061d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106419190613309565b503373ffffffffffffffffffffffffffffffffffffffff167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a9424364826040516106889190613c33565b60405180910390a2506001600955565b6000805b60025460ff8216101561071557600060028260ff16815481106106bb57fe5b60009182526020909120600d90910201805490915073ffffffffffffffffffffffffffffffffffffffff8581169116141561070c5760058101546202fd000143101561070c5760009250505061071b565b5060010161069c565b50600190505b919050565b600a5460ff161561075d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610580906136a2565b62278d00600854111561079c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105809061376d565b6003805473ffffffffffffffffffffffffffffffffffffffff9586167fffffffffffffffffffffffff000000000000000000000000000000000000000091821617909155600893909355600480549285169284169290921790915560058054919093169116179055600a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60025460005b8160ff168160ff1610156108575761084f8184610ace565b600101610837565b505050565b60025490565b60095460011461089e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613895565b60006009556006546040517f393a748400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063393a7484906108f990339060040161346d565b60206040518083038186803b15801561091157600080fd5b505afa158015610925573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109499190613309565b61097f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610580906137ca565b61098881612e10565b506001600955565b60005481565b60008060028560ff16815481106109a957fe5b60009182526020909120600d90910201600181015490915073ffffffffffffffffffffffffffffffffffffffff16806109e6578392505050610a8f565b6040517f2e81056600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821690632e81056690610a3a90889088906004016134bf565b60206040518083038186803b158015610a5257600080fd5b505afa158015610a66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a8a9190613341565b925050505b9392505050565b60085473ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604090206006015401919050565b61198081565b610ad7826113ba565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604081206002805491929160ff8616908110610b1057fe5b600091825260208083206007600d909302019182015460ff881684526001860190915260408320548554929450909291610b699190610b6390670de0b6b3a764000090610b5d9087612ffa565b9061304b565b90613097565b60088401549091508015610cfb5783600a0154431115610bfe5760ff8716600090815260058601602090815260408083205460048901909252822054610bae91613097565b90508015610bf857610bc083826130d4565b60ff89166000908152600588016020526040902054909350610be290826130d4565b60ff891660009081526005880160205260409020555b50610cfb565b8115610c5a576000610c156064610b5d8585612ffa565b9050610c218382613097565b60ff89166000908152600488016020526040902054909350610c4390826130d4565b60ff89166000908152600488016020526040902055505b600984015443811015610cf957600b850154600090610c9b90610b5d610c804386613097565b60ff8d16600090815260048c01602052604090205490612ffa565b60ff8a16600090815260058901602052604090205490915080821115610cf6576000610cc78383613097565b9050610cd382826130d4565b60ff8c16600090815260058b016020526040902055610cf286826130d4565b9550505b50505b505b8115610f9a5760ff87166000908152600386016020526040902054610d2090836130d4565b60ff88166000908152600387016020526040902055600c840154610d4490836130d4565b600c8501558454610d6390670de0b6b3a764000090610b5d9086612ffa565b60ff8816600090815260018701602090815260408083209390935560028801905290812054610d9290846130d4565b60ff8916600090815260028801602052604080822083905587546004805492517f70a0823100000000000000000000000000000000000000000000000000000000815294955073ffffffffffffffffffffffffffffffffffffffff9182169485936370a0823193610e06939116910161346d565b60206040518083038186803b158015610e1e57600080fd5b505afa158015610e32573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e569190613341565b90508015610f965760ff8a1660009081526002890160205260408120819055610e808b8486610996565b90506000828211610e915781610e93565b825b9050600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d1660f99858d846040518463ffffffff1660e01b8152600401610ef49392919061348e565b600060405180830381600087803b158015610f0e57600080fd5b505af1158015610f22573d6000803e3d6000fd5b505050508a73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff168d60ff167f16dc511f817964d1eb39e0c3e84ce317f07b5b12cdfa1f8c2f179a08836af51a888686604051610f8b93929190613c4a565b60405180910390a450505b5050505b50505050505050565b60028181548110610fb357600080fd5b60009182526020909120600d9091020180546001820154600283015460038401546004850154600586015460068701546007880154600889015460098a0154600a8b0154600b8c0154600c909c015473ffffffffffffffffffffffffffffffffffffffff9b8c169d50998b169b9a9098169996989597949693959294919390928d565b600954600114611072576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613895565b600060095560055473ffffffffffffffffffffffffffffffffffffffff1633146110c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613bc5565b600060028460ff16815481106110da57fe5b90600052602060002090600d02019050806005015443111580156110fe5750824311155b611134576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610580906138cc565b61113d846113ba565b600581018390556006810182905560405160ff8516907fd50c9d621671c3fc38b7813912936d3cee3f956bdbf5f6c61b5091f2ff2b0fd5906111829086908690613c3c565b60405180910390a2505060016009555050565b6009546001146111d1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613895565b600060095560055473ffffffffffffffffffffffffffffffffffffffff163314611227576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613bc5565b6006546040517fbd5b622a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063bd5b622a9061127d90849060040161346d565b60206040518083038186803b15801561129557600080fd5b505afa1580156112a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112cd9190613309565b611303576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613a1a565b61130c826113ba565b600060028360ff168154811061131e57fe5b60009182526020909120600d909102016001810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff851617905560405190915060ff8416907fe6b2c8a01867d369cd4952ca70fea492ef433a6ff31b8c8d15c4781f136e60ed906113a890859061346d565b60405180910390a25050600160095550565b600060028260ff16815481106113cc57fe5b90600052602060002090600d0201905060008160050154905060008143116113f457436113f6565b815b6004840154909150808211156114ff576003546040517f70a0823100000000000000000000000000000000000000000000000000000000815260009173ffffffffffffffffffffffffffffffffffffffff16906370a082319061145d90309060040161346d565b60206040518083038186803b15801561147557600080fd5b505afa158015611489573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ad9190613341565b905080156114f65760006114dd82610b5d670de0b6b3a76400006114d78b888a8d60060154611b8b565b90612ffa565b60078701549091506114ef90826130d4565b6007870155505b50600484018290555b5050505050565b60008060028360ff168154811061151957fe5b90600052602060002090600d0201905060008160060154905081600301544310806115475750816005015443115b156115575760009250505061071b565b600061156885434360010185611b8b565b835490915061158f90869073ffffffffffffffffffffffffffffffffffffffff1683610996565b95945050505050565b6009546001146115d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613895565b60006009556003546040517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116906323b872dd906116339033903090869060040161348e565b602060405180830381600087803b15801561164d57600080fd5b505af1158015611661573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116859190613309565b5061098833612e10565b60035473ffffffffffffffffffffffffffffffffffffffff1681565b6000806009546001146116ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613895565b60006009556006546040517f393a748400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063393a748490611745908c9060040161346d565b60206040518083038186803b15801561175d57600080fd5b505afa158015611771573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117959190613309565b6117cb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610580906136ff565b6117d487612ce0565b6003546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063095ea7b39061182c908c908b906004016134bf565b602060405180830381600087803b15801561184657600080fd5b505af115801561185a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061187e9190613309565b503373ffffffffffffffffffffffffffffffffffffffff167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a9424364886040516118c59190613c33565b60405180910390a26003546040517fb56b681d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8b81169263b56b681d9261193192909116908c908c908c908c908c908c906004016135b6565b6040805180830381600087803b15801561194a57600080fd5b505af115801561195e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119829190613359565b6001600955909a909950975050505050505050565b60075481565b6119a633610831565b565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604081206002805483919060ff87169081106119e157fe5b6000918252602082206007600d90920201908101546003546040517f70a0823100000000000000000000000000000000000000000000000000000000815292945090929173ffffffffffffffffffffffffffffffffffffffff909116906370a0823190611a5290309060040161346d565b60206040518083038186803b158015611a6a57600080fd5b505afa158015611a7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aa29190613341565b60058401549091506000438210611ab95743611abb565b815b60048601549091508082118015611ad157508315155b15611b08576000611af885610b5d670de0b6b3a76400006114d78f87898e60060154611b8b565b9050611b0486826130d4565b9550505b60ff8a16600090815260018801602090815260408083205460028b019092528220548954611b539291610b6391611b4d90670de0b6b3a764000090610b5d908d612ffa565b906130d4565b8754909150611b7a908c9073ffffffffffffffffffffffffffffffffffffffff1683610996565b985050505050505050505b92915050565b60008060028660ff1681548110611b9e57fe5b60009182526020909120600d90910201600281015490915073ffffffffffffffffffffffffffffffffffffffff1680611be857611bdf846114d78789613097565b92505050611c9b565b600382015460058301546040517e9fc04700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841692629fc04792611c46928b908b908b90600401613c60565b60206040518083038186803b158015611c5e57600080fd5b505afa158015611c72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c969190613341565b925050505b949350505050565b600954600114611cdf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613895565b600060095560055473ffffffffffffffffffffffffffffffffffffffff163314611d35576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613bc5565b60025460101015611d72576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613645565b6006546040517fbd5b622a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063bd5b622a90611dc8908b9060040161346d565b60206040518083038186803b158015611de057600080fd5b505afa158015611df4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e189190613309565b611e4e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613a1a565b6006546040517fa5120bd500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063a5120bd590611ea4908a9060040161346d565b60206040518083038186803b158015611ebc57600080fd5b505afa158015611ed0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ef49190613309565b611f2a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613a77565b80821115611f64576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610580906139bd565b854311611f715785611f73565b435b9550848610611fae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613838565b6064831115611fe9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613ad4565b611ff1612c9b565b6002604051806101a001604052808b73ffffffffffffffffffffffffffffffffffffffff1681526020018a73ffffffffffffffffffffffffffffffffffffffff1681526020018973ffffffffffffffffffffffffffffffffffffffff168152602001888152602001888152602001878152602001868152602001600081526020018581526020018481526020018381526020018484038152602001600081525090806001815401808255809150506001900390600052602060002090600d020160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e082015181600701556101008201518160080155610120820151816009015561014082015181600a015561016082015181600b015561018082015181600c015550506001600280549050037fa2c202ffa25e71dc0d2875a9b67a9e2572541a0a246c21d72355cca968fd4be160405160405180910390a25050600160095550505050505050565b60055473ffffffffffffffffffffffffffffffffffffffff1681565b600954600114612297576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613895565b60006009556006546040517fea74109e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063ea74109e906122f290309060040161346d565b60206040518083038186803b15801561230a57600080fd5b505afa15801561231e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123429190613309565b612378576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613960565b33600090815260016020526040902080546007546123969082613097565b600755600082556003546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063a9059cbb906123f590339085906004016134bf565b602060405180830381600087803b15801561240f57600080fd5b505af1158015612423573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124479190613309565b5060025460005b8160ff168160ff16101561248a5760ff81166000908152600180860160209081526040808420849055600288019091528220919091550161244e565b505060016009555050565b6000806009546001146124d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613895565b60006009556006546040517f393a748400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063393a74849061252f908d9060040161346d565b60206040518083038186803b15801561254757600080fd5b505afa15801561255b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061257f9190613309565b6125b5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610580906136ff565b6125be87612ce0565b6003546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063095ea7b390612616908d908b906004016134bf565b602060405180830381600087803b15801561263057600080fd5b505af1158015612644573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126689190613309565b503373ffffffffffffffffffffffffffffffffffffffff167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a9424364886040516126af9190613c33565b60405180910390a26003546040517fe1f4a78400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8c81169263e1f4a7849261271d92909116908d908d908d908d908d908d908d906004016134e5565b6040805180830381600087803b15801561273657600080fd5b505af115801561274a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061276e9190613359565b6001600955909b909a5098505050505050505050565b6009546001146127c0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613895565b600060095560055473ffffffffffffffffffffffffffffffffffffffff163314612816576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613bc5565b6006546040517fa5120bd500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063a5120bd59061286c90849060040161346d565b60206040518083038186803b15801561288457600080fd5b505afa158015612898573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128bc9190613309565b6128f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613a77565b6128fb826113ba565b600060028360ff168154811061290d57fe5b60009182526020909120600d909102016002810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff851617905560405190915060ff8416907fa5e6b0a10fde1bb3c6184cb03bd87ce234e172121088195454746cf4a2e8094d906113a890859061346d565b60006009546001146129d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613895565b60006009556006546040517f393a748400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063393a748490612a30908b9060040161346d565b60206040518083038186803b158015612a4857600080fd5b505afa158015612a5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a809190613309565b612ab6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610580906136ff565b612abf86612ce0565b6003546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063095ea7b390612b17908b908a906004016134bf565b602060405180830381600087803b158015612b3157600080fd5b505af1158015612b45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b699190613309565b503373ffffffffffffffffffffffffffffffffffffffff167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a942436487604051612bb09190613c33565b60405180910390a26003546040517febb5d2e900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a81169263ebb5d2e992612c1c92909116908b908b908b908b908b908b906004016135b6565b602060405180830381600087803b158015612c3657600080fd5b505af1158015612c4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c6e9190613341565b600160095598975050505050505050565b60045473ffffffffffffffffffffffffffffffffffffffff1681565b60025460005b8160ff168160ff161015612cc057612cb8816113ba565b600101612ca1565b5050565b60065473ffffffffffffffffffffffffffffffffffffffff1681565b3360009081526001602052604090208054821115612d2a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613b31565b6008546006820154612d3b916130d4565b421015612d74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613b8e565b612d7d33610831565b600754612d8a9083613097565b6007558054612d999083613097565b815560025460005b8160ff168160ff161015612e0a57612dea670de0b6b3a7640000610b5d60028460ff1681548110612dce57fe5b600091825260209091206007600d909202010154865490612ffa565b60ff82166000908152600180860160205260409091209190915501612da1565b50505050565b6007546003546040517f70a08231000000000000000000000000000000000000000000000000000000008152600092612ec292909173ffffffffffffffffffffffffffffffffffffffff909116906370a0823190612e7290309060040161346d565b60206040518083038186803b158015612e8a57600080fd5b505afa158015612e9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b639190613341565b905060008111612efe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613929565b600754612f0b90826130d4565b60075573ffffffffffffffffffffffffffffffffffffffff82166000908152600160205260409020612f3c83610831565b8054612f4890836130d4565b815560025460005b8160ff168160ff161015612f9d57612f7d670de0b6b3a7640000610b5d60028460ff1681548110612dce57fe5b60ff82166000908152600180860160205260409091209190915501612f50565b5042600683015560405173ffffffffffffffffffffffffffffffffffffffff8516907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c90612fec908690613c33565b60405180910390a250505050565b60008115806130155750508082028282828161301257fe5b04145b611b85576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613736565b6000808211613086576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613bfc565b81838161308f57fe5b049392505050565b80820382811115611b85576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105809061360e565b80820182811015611b85576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613801565b803573ffffffffffffffffffffffffffffffffffffffff8116811461071b57600080fd5b803560ff8116811461071b57600080fd5b600060208284031215613157578081fd5b610a8f82613111565b600080600080600080600080610100898b03121561317c578384fd5b61318589613111565b975061319360208a01613111565b96506131a160408a01613111565b9550606089013594506080890135935060a089013592506131c460c08a01613111565b915060e089013590509295985092959890939650565b60008060008060008060008060006101208a8c0312156131f8578081fd5b6132018a613111565b985061320f60208b01613111565b975061321d60408b01613111565b989b979a5097986060810135985060808101359760a0820135975060c0820135965060e08201359550610100909101359350915050565b600080600080600080600060e0888a03121561326e578283fd5b61327788613111565b965061328560208901613111565b95506040880135945060608801359350608088013592506132a860a08901613111565b915060c0880135905092959891949750929550565b600080600080608085870312156132d2578384fd5b6132db85613111565b9350602085013592506132f060408601613111565b91506132fe60608601613111565b905092959194509250565b60006020828403121561331a578081fd5b81518015158114610a8f578182fd5b60006020828403121561333a578081fd5b5035919050565b600060208284031215613352578081fd5b5051919050565b6000806040838503121561336b578182fd5b505080516020909101519092909150565b60006020828403121561338d578081fd5b610a8f82613135565b600080604083850312156133a8578182fd5b6133b183613135565b91506133bf60208401613111565b90509250929050565b6000806000606084860312156133dc578081fd5b6133e584613135565b92506133f360208501613111565b9150604084013590509250925092565b600080600060608486031215613417578081fd5b61342084613135565b95602085013595506040909401359392505050565b6000806000806080858703121561344a578182fd5b61345385613135565b966020860135965060408601359560600135945092505050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b73ffffffffffffffffffffffffffffffffffffffff9384168152919092166020820152604081019190915260600190565b73ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b73ffffffffffffffffffffffffffffffffffffffff9889168152968816602088015294871660408701526060860193909352608085019190915260a084015290921660c082015260e08101919091526101000190565b73ffffffffffffffffffffffffffffffffffffffff9d8e1681529b8d1660208d015299909b1660408b015260608a0197909752608089019590955260a088019390935260c087019190915260e08601526101008501526101208401526101408301526101608201929092526101808101919091526101a00190565b73ffffffffffffffffffffffffffffffffffffffff9788168152958716602087015260408601949094526060850192909252608084015290921660a082015260c081019190915260e00190565b901515815260200190565b60208082526015908201527f64732d6d6174682d7375622d756e646572666c6f770000000000000000000000604082015260600190565b60208082526022908201527f5374616b65506f6f6c3a2052657761726420706f6f6c206c656e677468203e2060408201527f3136000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526024908201527f5374616b65506f6f6c3a20496e697469616c697a65206d75737420626520666160408201527f6c73652e00000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601b908201527f5374616b65506f6f6c3a20496e76616c69642070726f76696465720000000000604082015260600190565b60208082526014908201527f64732d6d6174682d6d756c2d6f766572666c6f77000000000000000000000000604082015260600190565b60208082526028908201527f5374616b65506f6f6c3a20756e7374616b696e6746726f7a656e54696d65203e60408201527f2033302064617973000000000000000000000000000000000000000000000000606082015260800190565b60208082526019908201527f5374616b65506f6f6c3a20496e76616c69642073656e64657200000000000000604082015260600190565b60208082526014908201527f64732d6d6174682d6164642d6f766572666c6f77000000000000000000000000604082015260600190565b60208082526027908201527f5374616b65506f6f6c3a207374617274426c6f636b203e3d20656e645265776160408201527f7264426c6f636b00000000000000000000000000000000000000000000000000606082015260800190565b60208082526011908201527f5374616b65506f6f6c3a204c4f434b4544000000000000000000000000000000604082015260600190565b60208082526027908201527f5374616b65506f6f6c3a20626c6f636b4e756d626572203e20656e645265776160408201527f7264426c6f636b00000000000000000000000000000000000000000000000000606082015260800190565b6020808252601a908201527f5374616b65506f6f6c3a20496e76616c69642062616c616e6365000000000000604082015260600190565b60208082526026908201527f5374616b65506f6f6c3a204e6f7420616c6c6f7720656d657267656e6379576960408201527f7468647261770000000000000000000000000000000000000000000000000000606082015260800190565b6020808252602e908201527f5374616b65506f6f6c3a20737461727456657374696e67426c6f636b203e206560408201527f6e6456657374696e67426c6f636b000000000000000000000000000000000000606082015260800190565b60208082526021908201527f5374616b65506f6f6c3a20496e76616c6964207265776172642072656261736560408201527f7200000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526024908201527f5374616b65506f6f6c3a20496e76616c696420726577617264206d756c74697060408201527f6c69657200000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526024908201527f5374616b65506f6f6c3a20696e76616c6964206c6f636b52657761726450657260408201527f63656e7400000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526022908201527f5374616b65506f6f6c3a20696e76616c696420776974686472617720616d6f7560408201527f6e74000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526011908201527f5374616b65506f6f6c3a2066726f7a656e000000000000000000000000000000604082015260600190565b60208082526014908201527f5374616b65506f6f6c3a202174696d656c6f636b000000000000000000000000604082015260600190565b60208082526018908201527f64732d6d6174682d6469766973696f6e2d62792d7a65726f0000000000000000604082015260600190565b90815260200190565b918252602082015260400190565b9283526020830191909152604082015260600190565b948552602085019390935260408401919091526060830152608082015260a0019056fea2646970667358221220cc61c989077f5ccc64e8214e4583bf3c9d48d510812103a4013648f227694ce264736f6c63430007060033000000000000000000000000f0159d041db29029ccf285a1043dcaac7088030b0000000000000000000000000000000000000000000000000000000000000bb9

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102415760003560e01c806385cc179e11610145578063c0eac9ea116100bd578063e2589d381161008c578063efe2226611610071578063efe22266146104ad578063f36c0a72146104b5578063f77c4791146104bd57610241565b8063e2589d3814610487578063ebb5d2e91461049a57610241565b8063c0eac9ea14610451578063d33219b414610464578063db2e21bc1461046c578063e1f4a7841461047457610241565b8063b56b681d11610114578063b88a802f116100f9578063b88a802f14610423578063be6153351461042b578063c012c42e1461043e57610241565b8063b56b681d14610408578063b69ef8a81461041b57610241565b806385cc179e146103ba57806393ae1d1f146103cd578063a694fc3a146103e0578063a8aa1b31146103f357610241565b80634bf69206116101d85780636bb987fe116101a757806372aa0a601161018c57806372aa0a601461036857806376d743fe146103945780638583f6a5146103a757610241565b80636bb987fe1461034d5780636d3c6d921461035557610241565b80634bf692061461030c57806354fd4d501461031f578063597293f31461032757806360d470881461033a57610241565b80633468a5b8116102145780633468a5b8146102be578063358394d8146102de578063362a3fad146102f1578063437686491461030457610241565b806317837baa146102465780631959a0021461026457806329d79588146102855780632e1a7d4d146102a9575b600080fd5b61024e6104c5565b60405161025b9190613c33565b60405180910390f35b610277610272366004613146565b6104cb565b60405161025b929190613c3c565b610298610293366004613396565b6104e4565b60405161025b959493929190613c60565b6102bc6102b7366004613329565b610544565b005b6102d16102cc366004613146565b610698565b60405161025b9190613603565b6102bc6102ec3660046132bd565b610720565b6102bc6102ff366004613146565b610831565b61024e61085c565b6102bc61031a366004613146565b610862565b61024e610990565b61024e6103353660046133c8565b610996565b61024e610348366004613146565b610a96565b61024e610ac8565b6102bc610363366004613396565b610ace565b61037b610376366004613329565b610fa3565b60405161025b9d9c9b9a9998979695949392919061353b565b6102bc6103a2366004613403565b611036565b6102bc6103b5366004613396565b611195565b6102bc6103c836600461337c565b6113ba565b61024e6103db36600461337c565b611506565b6102bc6103ee366004613329565b611598565b6103fb61168f565b60405161025b919061346d565b610277610416366004613254565b6116ab565b61024e611997565b6102bc61199d565b61024e610439366004613396565b6119a8565b61024e61044c366004613435565b611b8b565b6102bc61045f3660046131da565b611ca3565b6103fb61223f565b6102bc61225b565b610277610482366004613160565b612495565b6102bc610495366004613396565b612784565b61024e6104a8366004613254565b612997565b6103fb612c7f565b6102bc612c9b565b6103fb612cc4565b60085481565b6001602052600090815260409020805460069091015482565b73ffffffffffffffffffffffffffffffffffffffff166000908152600160208181526040808420805460ff909616855292830182528084205460038401835281852054600485018452828620546005909501909352932054939492939092565b600954600114610589576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613895565b60405180910390fd5b600060095561059781612ce0565b6003546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063a9059cbb906105ef90339085906004016134bf565b602060405180830381600087803b15801561060957600080fd5b505af115801561061d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106419190613309565b503373ffffffffffffffffffffffffffffffffffffffff167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a9424364826040516106889190613c33565b60405180910390a2506001600955565b6000805b60025460ff8216101561071557600060028260ff16815481106106bb57fe5b60009182526020909120600d90910201805490915073ffffffffffffffffffffffffffffffffffffffff8581169116141561070c5760058101546202fd000143101561070c5760009250505061071b565b5060010161069c565b50600190505b919050565b600a5460ff161561075d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610580906136a2565b62278d00600854111561079c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105809061376d565b6003805473ffffffffffffffffffffffffffffffffffffffff9586167fffffffffffffffffffffffff000000000000000000000000000000000000000091821617909155600893909355600480549285169284169290921790915560058054919093169116179055600a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60025460005b8160ff168160ff1610156108575761084f8184610ace565b600101610837565b505050565b60025490565b60095460011461089e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613895565b60006009556006546040517f393a748400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063393a7484906108f990339060040161346d565b60206040518083038186803b15801561091157600080fd5b505afa158015610925573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109499190613309565b61097f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610580906137ca565b61098881612e10565b506001600955565b60005481565b60008060028560ff16815481106109a957fe5b60009182526020909120600d90910201600181015490915073ffffffffffffffffffffffffffffffffffffffff16806109e6578392505050610a8f565b6040517f2e81056600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821690632e81056690610a3a90889088906004016134bf565b60206040518083038186803b158015610a5257600080fd5b505afa158015610a66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a8a9190613341565b925050505b9392505050565b60085473ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604090206006015401919050565b61198081565b610ad7826113ba565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604081206002805491929160ff8616908110610b1057fe5b600091825260208083206007600d909302019182015460ff881684526001860190915260408320548554929450909291610b699190610b6390670de0b6b3a764000090610b5d9087612ffa565b9061304b565b90613097565b60088401549091508015610cfb5783600a0154431115610bfe5760ff8716600090815260058601602090815260408083205460048901909252822054610bae91613097565b90508015610bf857610bc083826130d4565b60ff89166000908152600588016020526040902054909350610be290826130d4565b60ff891660009081526005880160205260409020555b50610cfb565b8115610c5a576000610c156064610b5d8585612ffa565b9050610c218382613097565b60ff89166000908152600488016020526040902054909350610c4390826130d4565b60ff89166000908152600488016020526040902055505b600984015443811015610cf957600b850154600090610c9b90610b5d610c804386613097565b60ff8d16600090815260048c01602052604090205490612ffa565b60ff8a16600090815260058901602052604090205490915080821115610cf6576000610cc78383613097565b9050610cd382826130d4565b60ff8c16600090815260058b016020526040902055610cf286826130d4565b9550505b50505b505b8115610f9a5760ff87166000908152600386016020526040902054610d2090836130d4565b60ff88166000908152600387016020526040902055600c840154610d4490836130d4565b600c8501558454610d6390670de0b6b3a764000090610b5d9086612ffa565b60ff8816600090815260018701602090815260408083209390935560028801905290812054610d9290846130d4565b60ff8916600090815260028801602052604080822083905587546004805492517f70a0823100000000000000000000000000000000000000000000000000000000815294955073ffffffffffffffffffffffffffffffffffffffff9182169485936370a0823193610e06939116910161346d565b60206040518083038186803b158015610e1e57600080fd5b505afa158015610e32573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e569190613341565b90508015610f965760ff8a1660009081526002890160205260408120819055610e808b8486610996565b90506000828211610e915781610e93565b825b9050600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d1660f99858d846040518463ffffffff1660e01b8152600401610ef49392919061348e565b600060405180830381600087803b158015610f0e57600080fd5b505af1158015610f22573d6000803e3d6000fd5b505050508a73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff168d60ff167f16dc511f817964d1eb39e0c3e84ce317f07b5b12cdfa1f8c2f179a08836af51a888686604051610f8b93929190613c4a565b60405180910390a450505b5050505b50505050505050565b60028181548110610fb357600080fd5b60009182526020909120600d9091020180546001820154600283015460038401546004850154600586015460068701546007880154600889015460098a0154600a8b0154600b8c0154600c909c015473ffffffffffffffffffffffffffffffffffffffff9b8c169d50998b169b9a9098169996989597949693959294919390928d565b600954600114611072576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613895565b600060095560055473ffffffffffffffffffffffffffffffffffffffff1633146110c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613bc5565b600060028460ff16815481106110da57fe5b90600052602060002090600d02019050806005015443111580156110fe5750824311155b611134576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610580906138cc565b61113d846113ba565b600581018390556006810182905560405160ff8516907fd50c9d621671c3fc38b7813912936d3cee3f956bdbf5f6c61b5091f2ff2b0fd5906111829086908690613c3c565b60405180910390a2505060016009555050565b6009546001146111d1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613895565b600060095560055473ffffffffffffffffffffffffffffffffffffffff163314611227576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613bc5565b6006546040517fbd5b622a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063bd5b622a9061127d90849060040161346d565b60206040518083038186803b15801561129557600080fd5b505afa1580156112a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112cd9190613309565b611303576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613a1a565b61130c826113ba565b600060028360ff168154811061131e57fe5b60009182526020909120600d909102016001810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff851617905560405190915060ff8416907fe6b2c8a01867d369cd4952ca70fea492ef433a6ff31b8c8d15c4781f136e60ed906113a890859061346d565b60405180910390a25050600160095550565b600060028260ff16815481106113cc57fe5b90600052602060002090600d0201905060008160050154905060008143116113f457436113f6565b815b6004840154909150808211156114ff576003546040517f70a0823100000000000000000000000000000000000000000000000000000000815260009173ffffffffffffffffffffffffffffffffffffffff16906370a082319061145d90309060040161346d565b60206040518083038186803b15801561147557600080fd5b505afa158015611489573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ad9190613341565b905080156114f65760006114dd82610b5d670de0b6b3a76400006114d78b888a8d60060154611b8b565b90612ffa565b60078701549091506114ef90826130d4565b6007870155505b50600484018290555b5050505050565b60008060028360ff168154811061151957fe5b90600052602060002090600d0201905060008160060154905081600301544310806115475750816005015443115b156115575760009250505061071b565b600061156885434360010185611b8b565b835490915061158f90869073ffffffffffffffffffffffffffffffffffffffff1683610996565b95945050505050565b6009546001146115d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613895565b60006009556003546040517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116906323b872dd906116339033903090869060040161348e565b602060405180830381600087803b15801561164d57600080fd5b505af1158015611661573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116859190613309565b5061098833612e10565b60035473ffffffffffffffffffffffffffffffffffffffff1681565b6000806009546001146116ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613895565b60006009556006546040517f393a748400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063393a748490611745908c9060040161346d565b60206040518083038186803b15801561175d57600080fd5b505afa158015611771573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117959190613309565b6117cb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610580906136ff565b6117d487612ce0565b6003546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063095ea7b39061182c908c908b906004016134bf565b602060405180830381600087803b15801561184657600080fd5b505af115801561185a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061187e9190613309565b503373ffffffffffffffffffffffffffffffffffffffff167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a9424364886040516118c59190613c33565b60405180910390a26003546040517fb56b681d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8b81169263b56b681d9261193192909116908c908c908c908c908c908c906004016135b6565b6040805180830381600087803b15801561194a57600080fd5b505af115801561195e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119829190613359565b6001600955909a909950975050505050505050565b60075481565b6119a633610831565b565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604081206002805483919060ff87169081106119e157fe5b6000918252602082206007600d90920201908101546003546040517f70a0823100000000000000000000000000000000000000000000000000000000815292945090929173ffffffffffffffffffffffffffffffffffffffff909116906370a0823190611a5290309060040161346d565b60206040518083038186803b158015611a6a57600080fd5b505afa158015611a7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aa29190613341565b60058401549091506000438210611ab95743611abb565b815b60048601549091508082118015611ad157508315155b15611b08576000611af885610b5d670de0b6b3a76400006114d78f87898e60060154611b8b565b9050611b0486826130d4565b9550505b60ff8a16600090815260018801602090815260408083205460028b019092528220548954611b539291610b6391611b4d90670de0b6b3a764000090610b5d908d612ffa565b906130d4565b8754909150611b7a908c9073ffffffffffffffffffffffffffffffffffffffff1683610996565b985050505050505050505b92915050565b60008060028660ff1681548110611b9e57fe5b60009182526020909120600d90910201600281015490915073ffffffffffffffffffffffffffffffffffffffff1680611be857611bdf846114d78789613097565b92505050611c9b565b600382015460058301546040517e9fc04700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841692629fc04792611c46928b908b908b90600401613c60565b60206040518083038186803b158015611c5e57600080fd5b505afa158015611c72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c969190613341565b925050505b949350505050565b600954600114611cdf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613895565b600060095560055473ffffffffffffffffffffffffffffffffffffffff163314611d35576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613bc5565b60025460101015611d72576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613645565b6006546040517fbd5b622a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063bd5b622a90611dc8908b9060040161346d565b60206040518083038186803b158015611de057600080fd5b505afa158015611df4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e189190613309565b611e4e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613a1a565b6006546040517fa5120bd500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063a5120bd590611ea4908a9060040161346d565b60206040518083038186803b158015611ebc57600080fd5b505afa158015611ed0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ef49190613309565b611f2a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613a77565b80821115611f64576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610580906139bd565b854311611f715785611f73565b435b9550848610611fae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613838565b6064831115611fe9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613ad4565b611ff1612c9b565b6002604051806101a001604052808b73ffffffffffffffffffffffffffffffffffffffff1681526020018a73ffffffffffffffffffffffffffffffffffffffff1681526020018973ffffffffffffffffffffffffffffffffffffffff168152602001888152602001888152602001878152602001868152602001600081526020018581526020018481526020018381526020018484038152602001600081525090806001815401808255809150506001900390600052602060002090600d020160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e082015181600701556101008201518160080155610120820151816009015561014082015181600a015561016082015181600b015561018082015181600c015550506001600280549050037fa2c202ffa25e71dc0d2875a9b67a9e2572541a0a246c21d72355cca968fd4be160405160405180910390a25050600160095550505050505050565b60055473ffffffffffffffffffffffffffffffffffffffff1681565b600954600114612297576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613895565b60006009556006546040517fea74109e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063ea74109e906122f290309060040161346d565b60206040518083038186803b15801561230a57600080fd5b505afa15801561231e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123429190613309565b612378576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613960565b33600090815260016020526040902080546007546123969082613097565b600755600082556003546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063a9059cbb906123f590339085906004016134bf565b602060405180830381600087803b15801561240f57600080fd5b505af1158015612423573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124479190613309565b5060025460005b8160ff168160ff16101561248a5760ff81166000908152600180860160209081526040808420849055600288019091528220919091550161244e565b505060016009555050565b6000806009546001146124d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613895565b60006009556006546040517f393a748400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063393a74849061252f908d9060040161346d565b60206040518083038186803b15801561254757600080fd5b505afa15801561255b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061257f9190613309565b6125b5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610580906136ff565b6125be87612ce0565b6003546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063095ea7b390612616908d908b906004016134bf565b602060405180830381600087803b15801561263057600080fd5b505af1158015612644573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126689190613309565b503373ffffffffffffffffffffffffffffffffffffffff167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a9424364886040516126af9190613c33565b60405180910390a26003546040517fe1f4a78400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8c81169263e1f4a7849261271d92909116908d908d908d908d908d908d908d906004016134e5565b6040805180830381600087803b15801561273657600080fd5b505af115801561274a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061276e9190613359565b6001600955909b909a5098505050505050505050565b6009546001146127c0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613895565b600060095560055473ffffffffffffffffffffffffffffffffffffffff163314612816576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613bc5565b6006546040517fa5120bd500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063a5120bd59061286c90849060040161346d565b60206040518083038186803b15801561288457600080fd5b505afa158015612898573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128bc9190613309565b6128f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613a77565b6128fb826113ba565b600060028360ff168154811061290d57fe5b60009182526020909120600d909102016002810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff851617905560405190915060ff8416907fa5e6b0a10fde1bb3c6184cb03bd87ce234e172121088195454746cf4a2e8094d906113a890859061346d565b60006009546001146129d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613895565b60006009556006546040517f393a748400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063393a748490612a30908b9060040161346d565b60206040518083038186803b158015612a4857600080fd5b505afa158015612a5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a809190613309565b612ab6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610580906136ff565b612abf86612ce0565b6003546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063095ea7b390612b17908b908a906004016134bf565b602060405180830381600087803b158015612b3157600080fd5b505af1158015612b45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b699190613309565b503373ffffffffffffffffffffffffffffffffffffffff167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a942436487604051612bb09190613c33565b60405180910390a26003546040517febb5d2e900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a81169263ebb5d2e992612c1c92909116908b908b908b908b908b908b906004016135b6565b602060405180830381600087803b158015612c3657600080fd5b505af1158015612c4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c6e9190613341565b600160095598975050505050505050565b60045473ffffffffffffffffffffffffffffffffffffffff1681565b60025460005b8160ff168160ff161015612cc057612cb8816113ba565b600101612ca1565b5050565b60065473ffffffffffffffffffffffffffffffffffffffff1681565b3360009081526001602052604090208054821115612d2a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613b31565b6008546006820154612d3b916130d4565b421015612d74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613b8e565b612d7d33610831565b600754612d8a9083613097565b6007558054612d999083613097565b815560025460005b8160ff168160ff161015612e0a57612dea670de0b6b3a7640000610b5d60028460ff1681548110612dce57fe5b600091825260209091206007600d909202010154865490612ffa565b60ff82166000908152600180860160205260409091209190915501612da1565b50505050565b6007546003546040517f70a08231000000000000000000000000000000000000000000000000000000008152600092612ec292909173ffffffffffffffffffffffffffffffffffffffff909116906370a0823190612e7290309060040161346d565b60206040518083038186803b158015612e8a57600080fd5b505afa158015612e9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b639190613341565b905060008111612efe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613929565b600754612f0b90826130d4565b60075573ffffffffffffffffffffffffffffffffffffffff82166000908152600160205260409020612f3c83610831565b8054612f4890836130d4565b815560025460005b8160ff168160ff161015612f9d57612f7d670de0b6b3a7640000610b5d60028460ff1681548110612dce57fe5b60ff82166000908152600180860160205260409091209190915501612f50565b5042600683015560405173ffffffffffffffffffffffffffffffffffffffff8516907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c90612fec908690613c33565b60405180910390a250505050565b60008115806130155750508082028282828161301257fe5b04145b611b85576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613736565b6000808211613086576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613bfc565b81838161308f57fe5b049392505050565b80820382811115611b85576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105809061360e565b80820182811015611b85576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090613801565b803573ffffffffffffffffffffffffffffffffffffffff8116811461071b57600080fd5b803560ff8116811461071b57600080fd5b600060208284031215613157578081fd5b610a8f82613111565b600080600080600080600080610100898b03121561317c578384fd5b61318589613111565b975061319360208a01613111565b96506131a160408a01613111565b9550606089013594506080890135935060a089013592506131c460c08a01613111565b915060e089013590509295985092959890939650565b60008060008060008060008060006101208a8c0312156131f8578081fd5b6132018a613111565b985061320f60208b01613111565b975061321d60408b01613111565b989b979a5097986060810135985060808101359760a0820135975060c0820135965060e08201359550610100909101359350915050565b600080600080600080600060e0888a03121561326e578283fd5b61327788613111565b965061328560208901613111565b95506040880135945060608801359350608088013592506132a860a08901613111565b915060c0880135905092959891949750929550565b600080600080608085870312156132d2578384fd5b6132db85613111565b9350602085013592506132f060408601613111565b91506132fe60608601613111565b905092959194509250565b60006020828403121561331a578081fd5b81518015158114610a8f578182fd5b60006020828403121561333a578081fd5b5035919050565b600060208284031215613352578081fd5b5051919050565b6000806040838503121561336b578182fd5b505080516020909101519092909150565b60006020828403121561338d578081fd5b610a8f82613135565b600080604083850312156133a8578182fd5b6133b183613135565b91506133bf60208401613111565b90509250929050565b6000806000606084860312156133dc578081fd5b6133e584613135565b92506133f360208501613111565b9150604084013590509250925092565b600080600060608486031215613417578081fd5b61342084613135565b95602085013595506040909401359392505050565b6000806000806080858703121561344a578182fd5b61345385613135565b966020860135965060408601359560600135945092505050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b73ffffffffffffffffffffffffffffffffffffffff9384168152919092166020820152604081019190915260600190565b73ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b73ffffffffffffffffffffffffffffffffffffffff9889168152968816602088015294871660408701526060860193909352608085019190915260a084015290921660c082015260e08101919091526101000190565b73ffffffffffffffffffffffffffffffffffffffff9d8e1681529b8d1660208d015299909b1660408b015260608a0197909752608089019590955260a088019390935260c087019190915260e08601526101008501526101208401526101408301526101608201929092526101808101919091526101a00190565b73ffffffffffffffffffffffffffffffffffffffff9788168152958716602087015260408601949094526060850192909252608084015290921660a082015260c081019190915260e00190565b901515815260200190565b60208082526015908201527f64732d6d6174682d7375622d756e646572666c6f770000000000000000000000604082015260600190565b60208082526022908201527f5374616b65506f6f6c3a2052657761726420706f6f6c206c656e677468203e2060408201527f3136000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526024908201527f5374616b65506f6f6c3a20496e697469616c697a65206d75737420626520666160408201527f6c73652e00000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601b908201527f5374616b65506f6f6c3a20496e76616c69642070726f76696465720000000000604082015260600190565b60208082526014908201527f64732d6d6174682d6d756c2d6f766572666c6f77000000000000000000000000604082015260600190565b60208082526028908201527f5374616b65506f6f6c3a20756e7374616b696e6746726f7a656e54696d65203e60408201527f2033302064617973000000000000000000000000000000000000000000000000606082015260800190565b60208082526019908201527f5374616b65506f6f6c3a20496e76616c69642073656e64657200000000000000604082015260600190565b60208082526014908201527f64732d6d6174682d6164642d6f766572666c6f77000000000000000000000000604082015260600190565b60208082526027908201527f5374616b65506f6f6c3a207374617274426c6f636b203e3d20656e645265776160408201527f7264426c6f636b00000000000000000000000000000000000000000000000000606082015260800190565b60208082526011908201527f5374616b65506f6f6c3a204c4f434b4544000000000000000000000000000000604082015260600190565b60208082526027908201527f5374616b65506f6f6c3a20626c6f636b4e756d626572203e20656e645265776160408201527f7264426c6f636b00000000000000000000000000000000000000000000000000606082015260800190565b6020808252601a908201527f5374616b65506f6f6c3a20496e76616c69642062616c616e6365000000000000604082015260600190565b60208082526026908201527f5374616b65506f6f6c3a204e6f7420616c6c6f7720656d657267656e6379576960408201527f7468647261770000000000000000000000000000000000000000000000000000606082015260800190565b6020808252602e908201527f5374616b65506f6f6c3a20737461727456657374696e67426c6f636b203e206560408201527f6e6456657374696e67426c6f636b000000000000000000000000000000000000606082015260800190565b60208082526021908201527f5374616b65506f6f6c3a20496e76616c6964207265776172642072656261736560408201527f7200000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526024908201527f5374616b65506f6f6c3a20496e76616c696420726577617264206d756c74697060408201527f6c69657200000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526024908201527f5374616b65506f6f6c3a20696e76616c6964206c6f636b52657761726450657260408201527f63656e7400000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526022908201527f5374616b65506f6f6c3a20696e76616c696420776974686472617720616d6f7560408201527f6e74000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526011908201527f5374616b65506f6f6c3a2066726f7a656e000000000000000000000000000000604082015260600190565b60208082526014908201527f5374616b65506f6f6c3a202174696d656c6f636b000000000000000000000000604082015260600190565b60208082526018908201527f64732d6d6174682d6469766973696f6e2d62792d7a65726f0000000000000000604082015260600190565b90815260200190565b918252602082015260400190565b9283526020830191909152604082015260600190565b948552602085019390935260408401919091526060830152608082015260a0019056fea2646970667358221220cc61c989077f5ccc64e8214e4583bf3c9d48d510812103a4013648f227694ce264736f6c63430007060033

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

000000000000000000000000f0159d041db29029ccf285a1043dcaac7088030b0000000000000000000000000000000000000000000000000000000000000bb9

-----Decoded View---------------
Arg [0] : _controller (address): 0xf0159d041DB29029cCF285A1043DcAAc7088030b
Arg [1] : _version (uint256): 3001

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000f0159d041db29029ccf285a1043dcaac7088030b
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000bb9


Deployed Bytecode Sourcemap

30125:20732:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31942:43;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;31686:44;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;46625:611::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;:::i;41049:213::-;;;;;;:::i;:::-;;:::i;:::-;;32544:570;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;33179:521::-;;;;;;:::i;:::-;;:::i;41270:245::-;;;;;;:::i;:::-;;:::i;40072:118::-;;;:::i;39130:212::-;;;;;;:::i;:::-;;:::i;30198:31::-;;;:::i;37362:483::-;;;;;;:::i;:::-;;:::i;40198:164::-;;;;;;:::i;:::-;;:::i;32067:45::-;;;:::i;41616:3133::-;;;;;;:::i;:::-;;:::i;31737:38::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;;;;;;;;:::i;38356:581::-;;;;;;:::i;:::-;;:::i;36123:444::-;;;;;;:::i;:::-;;:::i;47473:923::-;;;;;;:::i;:::-;;:::i;37853:495::-;;;;;;:::i;:::-;;:::i;38945:177::-;;;;;;:::i;:::-;;:::i;31782:28::-;;;:::i;:::-;;;;;;;:::i;49150:837::-;;;;;;:::i;:::-;;:::i;31913:22::-;;;:::i;41523:85::-;;;:::i;44757:1148::-;;;;;;:::i;:::-;;:::i;36643:711::-;;;;;;:::i;:::-;;:::i;33708:1928::-;;;;;;:::i;:::-;;:::i;31849:23::-;;;:::i;45976:641::-;;;:::i;48404:738::-;;;;;;:::i;:::-;;:::i;35644:471::-;;;;;;:::i;:::-;;:::i;49995:859::-;;;;;;:::i;:::-;;:::i;31817:25::-;;;:::i;47244:221::-;;;:::i;31879:25::-;;;:::i;31942:43::-;;;;:::o;31686:44::-;;;;;;;;;;;;;;;;;;;:::o;46625:611::-;46969:18;;46756:14;46969:18;;;:8;:18;;;;;;;;47007:11;;47042:21;;;;;;:15;;;:21;;;;;;47094:22;;;:28;;;;;;47146:15;;;:21;;;;;;47199:23;;;;:29;;;;;;47007:11;;47042:21;;47094:28;;46625:611::o;41049:213::-;32319:8;;32331:1;32319:13;32311:43;;;;;;;;;;;;:::i;:::-;;;;;;;;;32376:1;32365:8;:12;41118:28:::1;41138:7:::0;41118:19:::1;:28::i;:::-;41174:4;::::0;41157:52:::1;::::0;;;;41174:4:::1;::::0;;::::1;::::0;41157:31:::1;::::0;:52:::1;::::0;41189:10:::1;::::0;41201:7;;41157:52:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;41234:10;41225:29;;;41246:7;41225:29;;;;;;:::i;:::-;;;;;;;;-1:-1:-1::0;32411:1:0;32400:8;:12;41049:213::o;32544:570::-;32625:4;;32642:443;32668:14;:21;32662:27;;;;32642:443;;;32713:33;32749:14;32764:3;32749:19;;;;;;;;;;;;;;;;;;;;;;;32787:22;;32749:19;;-1:-1:-1;32787:32:0;;;;:22;;:32;32783:291;;;32952:25;;;;32981:19;32952:49;32936:12;:66;32932:127;;;33034:5;33027:12;;;;;;32932:127;-1:-1:-1;32691:5:0;;32642:443;;;;33102:4;33095:11;;32544:570;;;;:::o;33179:521::-;33364:12;;;;:21;33356:70;;;;;;;;;;;;:::i;:::-;33468:7;33445:19;;:30;;33437:83;;;;;;;;;;;;:::i;:::-;33531:4;:12;;;;;;;;;;;;;;33554:19;:42;;;;33607:10;:24;;;;;;;;;;;;;;;33642:8;:20;;;;;;;;;;;33673:12;:19;;;;33531:12;33673:19;;;33179:521::o;41270:245::-;41369:14;:21;41338:22;41402:106;41430:16;41423:23;;:4;:23;;;41402:106;;;41471:25;41481:4;41487:8;41471:9;:25::i;:::-;41448:6;;41402:106;;;;41270:245;;:::o;40072:118::-;40161:14;:21;40072:118;:::o;39130:212::-;32319:8;;32331:1;32319:13;32311:43;;;;;;;;;;;;:::i;:::-;32376:1;32365:8;:12;39229:10:::1;::::0;39208:66:::1;::::0;;;;39229:10:::1;::::0;;::::1;::::0;39208:54:::1;::::0;:66:::1;::::0;39263:10:::1;::::0;39208:66:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;39200:104;;;;;;;;;;;;:::i;:::-;39315:19;39325:8;39315:9;:19::i;:::-;-1:-1:-1::0;32411:1:0;32400:8;:12;39130:212::o;30198:31::-;;;;:::o;37362:483::-;37509:7;37529:33;37565:14;37580:4;37565:20;;;;;;;;;;;;;;;;;;;;;;;37620:24;;;;37565:20;;-1:-1:-1;37620:24:0;;;37655:81;;37710:14;37703:21;;;;;;37655:81;37753:84;;;;;:54;;;;;;:84;;37808:12;;37822:14;;37753:84;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;37746:91;;;;37362:483;;;;;;:::o;40198:164::-;40335:19;;40300:18;;;40273:7;40300:18;;;:8;:18;;;;;:32;;;:54;40198:164;;;:::o;32067:45::-;32108:4;32067:45;:::o;41616:3133::-;41692:18;41705:4;41692:12;:18::i;:::-;41745;;;41721:21;41745:18;;;:8;:18;;;;;41810:14;:20;;41745:18;;41721:21;41810:20;;;;;;;;;;;;;;;;;;41870:28;41810:20;;;;;41870:28;;;;41984:21;;;;;:15;;;:21;;;;;;;41934:11;;41810:20;;-1:-1:-1;41870:28:0;;41810:20;41934:72;;41984:21;41934:45;;41974:4;;41934:35;;41870:28;41934:15;:35::i;:::-;:39;;:45::i;:::-;:49;;:72::i;:::-;42046:28;;;;41909:97;;-1:-1:-1;42089:22:0;;42085:1503;;42147:10;:26;;;42132:12;:41;42128:1449;;;42244:29;;;42194:21;42244:29;;;:23;;;:29;;;;;;;;;42218:15;;;:21;;;;;;:56;;:25;:56::i;:::-;42194:80;-1:-1:-1;42297:17:0;;42293:219;;42356:33;:14;42375:13;42356:18;:33::i;:::-;42444:29;;;;;;;:23;;;:29;;;;;;42339:50;;-1:-1:-1;42444:48:0;;42478:13;42444:33;:48::i;:::-;42412:29;;;;;;;:23;;;:29;;;;;:80;42293:219;42128:1449;;;;42556:18;;42552:286;;42599:17;42619:47;42662:3;42619:38;:14;42638:18;42619;:38::i;:47::-;42599:67;-1:-1:-1;42706:29:0;:14;42599:67;42706:18;:29::i;:::-;42782:21;;;;;;;:15;;;:21;;;;;;42689:46;;-1:-1:-1;42782:36:0;;42808:9;42782:25;:36::i;:::-;42758:21;;;;;;;:15;;;:21;;;;;:60;-1:-1:-1;42552:286:0;42885:28;;;;42936:12;:33;-1:-1:-1;42932:630:0;;;43084:29;;;;42994:19;;43016:98;;:63;43042:36;:12;43059:18;43042:16;:36::i;:::-;43016:21;;;;;;;:15;;;:21;;;;;;;:25;:63::i;:98::-;43167:29;;;43137:27;43167:29;;;:23;;;:29;;;;;;42994:120;;-1:-1:-1;43223:33:0;;;43219:324;;;43285:21;43309:36;:11;43325:19;43309:15;:36::i;:::-;43285:60;-1:-1:-1;43404:38:0;:19;43285:60;43404:23;:38::i;:::-;43372:29;;;;;;;:23;;;:29;;;;;:70;43486:33;:14;43505:13;43486:18;:33::i;:::-;43469:50;;43219:324;;42932:630;;;42128:1449;;43602:18;;43598:1144;;43668:28;;;;;;;:22;;;:28;;;;;;:48;;43701:14;43668:32;:48::i;:::-;43637:28;;;;;;;:22;;;:28;;;;;:79;43761:27;;;;:47;;43793:14;43761:31;:47::i;:::-;43731:27;;;:77;43847:11;;:45;;43887:4;;43847:35;;43863:18;43847:15;:35::i;:45::-;43823:21;;;;;;;:15;;;:21;;;;;;;;:69;;;;43924:11;;;:17;;;;;;:37;;43946:14;43924:21;:37::i;:::-;43976:17;;;;;;;:11;;;:17;;;;;;:26;;;44153:22;;44244:10;;;44214:41;;;;;43907:54;;-1:-1:-1;44153:22:0;;;;;;;44214:29;;:41;;44244:10;;;44214:41;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;44190:65;-1:-1:-1;44274:17:0;;44270:461;;44312:17;;;44332:1;44312:17;;;:11;;;:17;;;;;:21;;;44375:42;44324:4;44397:11;44410:6;44375:15;:42::i;:::-;44352:65;;44436:18;44472:13;44457:12;:28;:59;;44504:12;44457:59;;;44488:13;44457:59;44436:80;;44556:10;;;;;;;;;;;44535:45;;;44581:11;44594:8;44604:10;44535:80;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44672:8;44639:76;;44659:11;44639:76;;44653:4;44639:76;;;44682:6;44690:12;44704:10;44639:76;;;;;;;;:::i;:::-;;;;;;;;44270:461;;;43598:1144;;;;41616:3133;;;;;;;:::o;31737:38::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;31737:38:0;;;;;;;;;;;;;;;;;;;;;;;;:::o;38356:581::-;32319:8;;32331:1;32319:13;32311:43;;;;;;;;;;;;:::i;:::-;32376:1;32365:8;:12;32483:8:::1;::::0;::::1;;32469:10;:22;32461:55;;;;;;;;;;;;:::i;:::-;38525:33:::2;38561:14;38576:4;38561:20;;;;;;;;;;;;;;;;;;;;38525:56;;38616:10;:25;;;38600:12;:41;;:76;;;;;38661:15;38645:12;:31;;38600:76;38592:128;;;;;;;;;;;;:::i;:::-;38731:18;38744:4;38731:12;:18::i;:::-;38760:25;::::0;::::2;:43:::0;;;38814:25:::2;::::0;::::2;:43:::0;;;38873:56:::2;::::0;::::2;::::0;::::2;::::0;::::2;::::0;::::2;::::0;38788:15;;38842;;38873:56:::2;:::i;:::-;;;;;;;;-1:-1:-1::0;;32411:1:0;32400:8;:12;-1:-1:-1;;38356:581:0:o;36123:444::-;32319:8;;32331:1;32319:13;32311:43;;;;;;;;;;;;:::i;:::-;32376:1;32365:8;:12;32483:8:::1;::::0;::::1;;32469:10;:22;32461:55;;;;;;;;;;;;:::i;:::-;36264:10:::2;::::0;36243:73:::2;::::0;;;;36264:10:::2;::::0;;::::2;::::0;36243:57:::2;::::0;:73:::2;::::0;36301:14;;36243:73:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;36235:119;;;;;;;;;;;;:::i;:::-;36365:18;36378:4;36365:12;:18::i;:::-;36394:33;36430:14;36445:4;36430:20;;;;;;;;;;;::::0;;;::::2;::::0;;;::::2;::::0;;::::2;;36461:24;::::0;::::2;:41:::0;;;::::2;;::::0;::::2;;::::0;;36518::::2;::::0;36430:20;;-1:-1:-1;36518:41:0::2;::::0;::::2;::::0;::::2;::::0;::::2;::::0;36461;;36518::::2;:::i;:::-;;;;;;;;-1:-1:-1::0;;32411:1:0;32400:8;:12;-1:-1:-1;36123:444:0:o;47473:923::-;47534:33;47570:14;47585:4;47570:20;;;;;;;;;;;;;;;;;;;;47534:56;;47601:23;47627:10;:25;;;47601:51;;47663:33;47714:15;47699:12;:30;:63;;47750:12;47699:63;;;47732:15;47699:63;47800:26;;;;47663:99;;-1:-1:-1;47841:44:0;;;47837:552;;;47938:4;;47921:47;;;;;47902:16;;47938:4;;;47921:32;;:47;;47962:4;;47921:47;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47902:66;-1:-1:-1;47987:12:0;;47983:326;;48020:26;48070:121;48182:8;48070:107;48172:4;48070:97;48090:4;48096:16;48114:25;48141:10;:25;;;48070:19;:97::i;:::-;:101;;:107::i;:121::-;48241:28;;;;48020:171;;-1:-1:-1;48241:52:0;;48020:171;48241:32;:52::i;:::-;48210:28;;;:83;-1:-1:-1;47983:326:0;-1:-1:-1;48323:26:0;;;:54;;;47837:552;47473:923;;;;;:::o;37853:495::-;37923:7;37943:33;37979:14;37994:3;37979:19;;;;;;;;;;;;;;;;;;;;37943:55;;38009:22;38034:10;:25;;;38009:50;;38089:10;:27;;;38074:12;:42;:86;;;;38135:10;:25;;;38120:12;:40;38074:86;38070:100;;;38169:1;38162:8;;;;;;38070:100;38181:14;38198:72;38218:3;38223:12;38237;38252:1;38237:16;38255:14;38198:19;:72::i;:::-;38309:22;;38181:89;;-1:-1:-1;38288:52:0;;38304:3;;38309:22;;38181:89;38288:15;:52::i;:::-;38281:59;37853:495;-1:-1:-1;;;;;37853:495:0:o;38945:177::-;32319:8;;32331:1;32319:13;32311:43;;;;;;;;;;;;:::i;:::-;32376:1;32365:8;:12;39028:4:::1;::::0;39011:71:::1;::::0;;;;39028:4:::1;::::0;;::::1;::::0;39011:35:::1;::::0;:71:::1;::::0;39047:10:::1;::::0;39067:4:::1;::::0;39074:7;;39011:71:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;39093:21;39103:10;39093:9;:21::i;31782:28::-:0;;;;;;:::o;49150:837::-;49408:19;49429:17;32319:8;;32331:1;32319:13;32311:43;;;;;;;;;;;;:::i;:::-;32376:1;32365:8;:12;49488:10:::1;::::0;49467:64:::1;::::0;;;;49488:10:::1;::::0;;::::1;::::0;49467:54:::1;::::0;:64:::1;::::0;49522:8;;49467:64:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49459:104;;;;;;;;;;;;:::i;:::-;49574:30;49594:9;49574:19;:30::i;:::-;49632:4;::::0;49615:51:::1;::::0;;;;49632:4:::1;::::0;;::::1;::::0;49615:30:::1;::::0;:51:::1;::::0;49646:8;;49656:9;;49615:51:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;49691:10;49682:31;;;49703:9;49682:31;;;;;;:::i;:::-;;;;;;;;49823:4;::::0;49751:228:::1;::::0;;;;:49:::1;::::0;;::::1;::::0;::::1;::::0;:228:::1;::::0;49823:4;;::::1;::::0;49843:5;;49863:9;;49887:14;;49916:12;;49943:2;;49960:8;;49751:228:::1;;;:::i;:::-;;::::0;::::1;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;32411:1:::0;32400:8;:12;49724:255;;;;-1:-1:-1;49150:837:0;-1:-1:-1;;;;;;;;49150:837:0:o;31913:22::-;;;;:::o;41523:85::-;41575:25;41589:10;41575:13;:25::i;:::-;41523:85::o;44757:1148::-;44886:18;;;44842:7;44886:18;;;:8;:18;;;;;44951:14;:20;;44842:7;;44951:14;:20;;;;;;;;;;;;;;;;;45011:28;44951:20;;;;;45011:28;;;;45086:4;;45069:47;;;;;44951:20;;-1:-1:-1;45011:28:0;;44951:20;45086:4;;;;;45069:32;;:47;;45110:4;;45069:47;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;45153:25;;;;45050:66;;-1:-1:-1;45127:23:0;45225:12;:30;-1:-1:-1;45225:63:0;;45276:12;45225:63;;;45258:15;45225:63;45326:26;;;;45189:99;;-1:-1:-1;45367:44:0;;;:61;;;;-1:-1:-1;45415:13:0;;;45367:61;45363:339;;;45445:26;45491:121;45603:8;45491:107;45593:4;45491:97;45511:4;45517:16;45535:25;45562:10;:25;;;45491:19;:97::i;:121::-;45445:167;-1:-1:-1;45648:42:0;:18;45445:167;45648:22;:42::i;:::-;45627:63;;45363:339;;45803:21;;;45712:15;45803:21;;;:15;;;:21;;;;;;;;;45780:11;;;:17;;;;;;45730:11;;:95;;45803:21;45730:68;;:45;;45770:4;;45730:35;;45746:18;45730:15;:35::i;:45::-;:49;;:68::i;:95::-;45865:22;;45712:113;;-1:-1:-1;45843:54:0;;45859:4;;45865:22;;45712:113;45843:15;:54::i;:::-;45836:61;;;;;;;;;;44757:1148;;;;;:::o;36643:711::-;36810:7;36830:33;36866:14;36881:4;36866:20;;;;;;;;;;;;;;;;;;;;;;;36924:27;;;;36866:20;;-1:-1:-1;36924:27:0;;;36962:105;;37020:35;37039:15;37020:14;:3;37028:5;37020:7;:14::i;:35::-;37013:42;;;;;;36962:105;37180:27;;;;37226:25;;;;37097:249;;;;;:64;;;;;;:249;;37270:5;;37294:3;;37316:15;;37097:249;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;37077:269;;;;36643:711;;;;;;;:::o;33708:1928::-;32319:8;;32331:1;32319:13;32311:43;;;;;;;;;;;;:::i;:::-;32376:1;32365:8;:12;32483:8:::1;::::0;::::1;;32469:10;:22;32461:55;;;;;;;;;;;;:::i;:::-;34100:14:::2;:21:::0;34125:2:::2;-1:-1:-1::0;34100:27:0::2;34092:74;;;;;;;;;;;;:::i;:::-;34206:10;::::0;34185:73:::2;::::0;;;;34206:10:::2;::::0;;::::2;::::0;34185:57:::2;::::0;:73:::2;::::0;34243:14;;34185:73:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;34177:119;;;;;;;;;;;;:::i;:::-;34336:10;::::0;34315:79:::2;::::0;;;;34336:10:::2;::::0;;::::2;::::0;34315:60:::2;::::0;:79:::2;::::0;34376:17;;34315:79:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;34307:128;;;;;;;;;;;;:::i;:::-;34476:16;34454:18;:38;;34446:97;;;;;;;;;;;;:::i;:::-;34584:11;34569:12;:26;34568:57;;34614:11;34568:57;;;34599:12;34568:57;34554:71;;34658:15;34644:11;:29;34636:81;;;;;;;;;;;;:::i;:::-;34758:3;34736:18;:25;;34728:74;;;;;;;;;;;;:::i;:::-;34813:14;:12;:14::i;:::-;34838;34872:689;;;;;;;;34919:12;34872:689;;;;;;34965:14;34872:689;;;;;;35064:17;34872:689;;;;;;35016:11;34872:689;;;;35117:11;34872:689;;;;35163:15;34872:689;;;;35213:15;34872:689;;;;35266:1;34872:689;;;;35305:18;34872:689;;;;35361:18;34872:689;;;;35415:16;34872:689;;;;35489:18;35470:16;:37;34872:689;;;;35544:1;34872:689;;::::0;34838:734:::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35626:1;35602:14;:21;;;;:25;35588:40;;;;;;;;;;-1:-1:-1::0;;32411:1:0;32400:8;:12;-1:-1:-1;;;;;;;33708:1928:0:o;31849:23::-;;;;;;:::o;45976:641::-;32319:8;;32331:1;32319:13;32311:43;;;;;;;;;;;;:::i;:::-;32376:1;32365:8;:12;46068:10:::1;::::0;46047:81:::1;::::0;;;;46068:10:::1;::::0;;::::1;::::0;46047:66:::1;::::0;:81:::1;::::0;46122:4:::1;::::0;46047:81:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;46039:132;;;;;;;;;;;;:::i;:::-;46215:10;46182:21;46206:20:::0;;;:8:::1;:20;::::0;;;;46254:11;;46286:7:::1;::::0;:19:::1;::::0;46254:11;46286::::1;:19::i;:::-;46276:7;:29:::0;46330:1:::1;46316:15:::0;;46359:4:::1;::::0;46342:51:::1;::::0;;;;46359:4:::1;::::0;;::::1;::::0;46342:31:::1;::::0;:51:::1;::::0;46374:10:::1;::::0;46386:6;;46342:51:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;46435:14:0::1;:21:::0;46404:22:::1;46468:142;46496:16;46489:23;;:4;:23;;;46468:142;;;46537:21;::::0;::::1;46561:1;46537:21:::0;;;:15:::1;::::0;;::::1;:21;::::0;;;;;;;:25;;;46577:11:::1;::::0;::::1;:17:::0;;;;;:21;;;;46514:6:::1;46468:142;;;-1:-1:-1::0;;32411:1:0;32400:8;:12;-1:-1:-1;;45976:641:0:o;48404:738::-;48677:15;48694;32319:8;;32331:1;32319:13;32311:43;;;;;;;;;;;;:::i;:::-;32376:1;32365:8;:12;48751:10:::1;::::0;48730:64:::1;::::0;;;;48751:10:::1;::::0;;::::1;::::0;48730:54:::1;::::0;:64:::1;::::0;48785:8;;48730:64:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;48722:104;;;;;;;;;;;;:::i;:::-;48837:30;48857:9;48837:19;:30::i;:::-;48895:4;::::0;48878:51:::1;::::0;;;;48895:4:::1;::::0;;::::1;::::0;48878:30:::1;::::0;:51:::1;::::0;48909:8;;48919:9;;48878:51:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;48954:10;48945:31;;;48966:9;48945:31;;;;;;:::i;:::-;;;;;;;;49063:4;::::0;49008:126:::1;::::0;;;;:46:::1;::::0;;::::1;::::0;::::1;::::0;:126:::1;::::0;49063:4;;::::1;::::0;49070:6;;49078;;49086:9;;49097:10;;49109;;49121:2;;49125:8;;49008:126:::1;;;:::i;:::-;;::::0;::::1;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;32411:1:::0;32400:8;:12;48987:147;;;;-1:-1:-1;48404:738:0;-1:-1:-1;;;;;;;;;48404:738:0:o;35644:471::-;32319:8;;32331:1;32319:13;32311:43;;;;;;;;;;;;:::i;:::-;32376:1;32365:8;:12;32483:8:::1;::::0;::::1;;32469:10;:22;32461:55;;;;;;;;;;;;:::i;:::-;35791:10:::2;::::0;35770:79:::2;::::0;;;;35791:10:::2;::::0;;::::2;::::0;35770:60:::2;::::0;:79:::2;::::0;35831:17;;35770:79:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;35762:128;;;;;;;;;;;;:::i;:::-;35901:18;35914:4;35901:12;:18::i;:::-;35930:33;35966:14;35981:4;35966:20;;;;;;;;;;;::::0;;;::::2;::::0;;;::::2;::::0;;::::2;;35997:27;::::0;::::2;:47:::0;;;::::2;;::::0;::::2;;::::0;;36060::::2;::::0;35966:20;;-1:-1:-1;36060:47:0::2;::::0;::::2;::::0;::::2;::::0;::::2;::::0;35997;;36060::::2;:::i;49995:859::-:0;50282:17;32319:8;;32331:1;32319:13;32311:43;;;;;;;;;;;;:::i;:::-;32376:1;32365:8;:12;50341:10:::1;::::0;50320:64:::1;::::0;;;;50341:10:::1;::::0;;::::1;::::0;50320:54:::1;::::0;:64:::1;::::0;50375:8;;50320:64:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50312:104;;;;;;;;;;;;:::i;:::-;50427:30;50447:9;50427:19;:30::i;:::-;50485:4;::::0;50468:51:::1;::::0;;;;50485:4:::1;::::0;;::::1;::::0;50468:30:::1;::::0;:51:::1;::::0;50499:8;;50509:9;;50468:51:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;50544:10;50535:31;;;50556:9;50535:31;;;;;;:::i;:::-;;;;;;;;50690:4;::::0;50589:257:::1;::::0;;;;:78:::1;::::0;;::::1;::::0;::::1;::::0;:257:::1;::::0;50690:4;;::::1;::::0;50710:5;;50730:9;;50754:14;;50783:12;;50810:2;;50827:8;;50589:257:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;32411:1:::0;32400:8;:12;50577:269;49995:859;-1:-1:-1;;;;;;;;49995:859:0:o;31817:25::-;;;;;;:::o;47244:221::-;47326:14;:21;47295:22;47359:99;47387:16;47380:23;;:4;:23;;;47359:99;;;47428:18;47441:4;47428:12;:18::i;:::-;47405:6;;47359:99;;;;47244:221;:::o;31879:25::-;;;;;;:::o;40370:671::-;40469:10;40436:21;40460:20;;;:8;:20;;;;;40499:11;;:22;-1:-1:-1;40499:22:0;40491:69;;;;;;;;;;;;:::i;:::-;40621:19;;40598:18;;;;:43;;:22;:43::i;:::-;40579:15;:62;;40571:92;;;;;;;;;;;;:::i;:::-;40674:25;40688:10;40674:13;:25::i;:::-;40720:7;;:20;;40732:7;40720:11;:20::i;:::-;40710:7;:30;40765:11;;:24;;40781:7;40765:15;:24::i;:::-;40751:38;;40831:14;:21;40751:11;40864:170;40892:16;40885:23;;:4;:23;;;40864:170;;;40957:65;41017:4;40957:55;40973:14;40988:4;40973:20;;;;;;;;;;;;;;;;;;:38;:20;;;;;:38;;40957:11;;;:15;:55::i;:65::-;40933:21;;;;;;;:15;;;;:21;;;;;;:89;;;;40910:6;40864:170;;;;40370:671;;;:::o;39350:714::-;39477:7;;39442:4;;39425:47;;;;;39407:15;;39425:60;;39477:7;;39442:4;;;;;39425:32;;:47;;39466:4;;39425:47;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:60::-;39407:78;;39514:1;39504:7;:11;39496:50;;;;;;;;;;;;:::i;:::-;39567:7;;:20;;39579:7;39567:11;:20::i;:::-;39557:7;:30;39622:18;;;39598:21;39622:18;;;:8;:18;;;;;39651:23;39631:8;39651:13;:23::i;:::-;39699:11;;:24;;39715:7;39699:15;:24::i;:::-;39685:38;;39765:14;:21;39685:11;39798:170;39826:16;39819:23;;:4;:23;;;39798:170;;;39891:65;39951:4;39891:55;39907:14;39922:4;39907:20;;;;;;;;;39891:65;39867:21;;;;;;;:15;;;;:21;;;;;;:89;;;;39844:6;39798:170;;;-1:-1:-1;39999:15:0;39978:18;;;:36;40030:26;;;;;;;;;;40048:7;;40030:26;:::i;:::-;;;;;;;;39350:714;;;;:::o;12732:151::-;12790:9;12820:6;;;:30;;-1:-1:-1;;12835:5:0;;;12849:1;12844;12835:5;12844:1;12830:15;;;;;:20;12820:30;12812:63;;;;;;;;;;;;:::i;12891:150::-;12949:9;12983:1;12979;:5;12971:42;;;;;;;;;;;;:::i;:::-;13032:1;13028;:5;;;;;;;12891:150;-1:-1:-1;;;12891:150:0:o;12586:138::-;12679:5;;;12674:16;;;;12666:50;;;;;;;;;;;;:::i;12441:137::-;12534:5;;;12529:16;;;;12521:49;;;;;;;;;;;;:::i;14:198:1:-;84:20;;144:42;133:54;;123:65;;113:2;;202:1;199;192:12;217:158;285:20;;345:4;334:16;;324:27;;314:2;;365:1;362;355:12;380:198;;492:2;480:9;471:7;467:23;463:32;460:2;;;513:6;505;498:22;460:2;541:31;562:9;541:31;:::i;583:703::-;;;;;;;;;814:3;802:9;793:7;789:23;785:33;782:2;;;836:6;828;821:22;782:2;864:31;885:9;864:31;:::i;:::-;854:41;;914:40;950:2;939:9;935:18;914:40;:::i;:::-;904:50;;973:40;1009:2;998:9;994:18;973:40;:::i;:::-;963:50;;1060:2;1049:9;1045:18;1032:32;1022:42;;1111:3;1100:9;1096:19;1083:33;1073:43;;1163:3;1152:9;1148:19;1135:33;1125:43;;1187:41;1223:3;1212:9;1208:19;1187:41;:::i;:::-;1177:51;;1275:3;1264:9;1260:19;1247:33;1237:43;;772:514;;;;;;;;;;;:::o;1291:764::-;;;;;;;;;;1539:3;1527:9;1518:7;1514:23;1510:33;1507:2;;;1561:6;1553;1546:22;1507:2;1589:31;1610:9;1589:31;:::i;:::-;1579:41;;1639:40;1675:2;1664:9;1660:18;1639:40;:::i;:::-;1629:50;;1698:40;1734:2;1723:9;1719:18;1698:40;:::i;:::-;1497:558;;;;-1:-1:-1;1688:50:1;;1785:2;1770:18;;1757:32;;-1:-1:-1;1836:3:1;1821:19;;1808:33;;1888:3;1873:19;;1860:33;;-1:-1:-1;1940:3:1;1925:19;;1912:33;;-1:-1:-1;1992:3:1;1977:19;;1964:33;;-1:-1:-1;2044:3:1;2029:19;;;2016:33;;-1:-1:-1;1497:558:1;-1:-1:-1;;1497:558:1:o;2060:626::-;;;;;;;;2274:3;2262:9;2253:7;2249:23;2245:33;2242:2;;;2296:6;2288;2281:22;2242:2;2324:31;2345:9;2324:31;:::i;:::-;2314:41;;2374:40;2410:2;2399:9;2395:18;2374:40;:::i;:::-;2364:50;;2461:2;2450:9;2446:18;2433:32;2423:42;;2512:2;2501:9;2497:18;2484:32;2474:42;;2563:3;2552:9;2548:19;2535:33;2525:43;;2587:41;2623:3;2612:9;2608:19;2587:41;:::i;:::-;2577:51;;2675:3;2664:9;2660:19;2647:33;2637:43;;2232:454;;;;;;;;;;:::o;2691:419::-;;;;;2854:3;2842:9;2833:7;2829:23;2825:33;2822:2;;;2876:6;2868;2861:22;2822:2;2904:31;2925:9;2904:31;:::i;:::-;2894:41;;2982:2;2971:9;2967:18;2954:32;2944:42;;3005:40;3041:2;3030:9;3026:18;3005:40;:::i;:::-;2995:50;;3064:40;3100:2;3089:9;3085:18;3064:40;:::i;:::-;3054:50;;2812:298;;;;;;;:::o;3115:297::-;;3235:2;3223:9;3214:7;3210:23;3206:32;3203:2;;;3256:6;3248;3241:22;3203:2;3293:9;3287:16;3346:5;3339:13;3332:21;3325:5;3322:32;3312:2;;3373:6;3365;3358:22;3417:190;;3529:2;3517:9;3508:7;3504:23;3500:32;3497:2;;;3550:6;3542;3535:22;3497:2;-1:-1:-1;3578:23:1;;3487:120;-1:-1:-1;3487:120:1:o;3612:194::-;;3735:2;3723:9;3714:7;3710:23;3706:32;3703:2;;;3756:6;3748;3741:22;3703:2;-1:-1:-1;3784:16:1;;3693:113;-1:-1:-1;3693:113:1:o;3811:255::-;;;3951:2;3939:9;3930:7;3926:23;3922:32;3919:2;;;3972:6;3964;3957:22;3919:2;-1:-1:-1;;4000:16:1;;4056:2;4041:18;;;4035:25;4000:16;;4035:25;;-1:-1:-1;3909:157:1:o;4071:194::-;;4181:2;4169:9;4160:7;4156:23;4152:32;4149:2;;;4202:6;4194;4187:22;4149:2;4230:29;4249:9;4230:29;:::i;4270:270::-;;;4397:2;4385:9;4376:7;4372:23;4368:32;4365:2;;;4418:6;4410;4403:22;4365:2;4446:29;4465:9;4446:29;:::i;:::-;4436:39;;4494:40;4530:2;4519:9;4515:18;4494:40;:::i;:::-;4484:50;;4355:185;;;;;:::o;4545:338::-;;;;4689:2;4677:9;4668:7;4664:23;4660:32;4657:2;;;4710:6;4702;4695:22;4657:2;4738:29;4757:9;4738:29;:::i;:::-;4728:39;;4786:40;4822:2;4811:9;4807:18;4786:40;:::i;:::-;4776:50;;4873:2;4862:9;4858:18;4845:32;4835:42;;4647:236;;;;;:::o;4888:330::-;;;;5032:2;5020:9;5011:7;5007:23;5003:32;5000:2;;;5053:6;5045;5038:22;5000:2;5081:29;5100:9;5081:29;:::i;:::-;5071:39;5157:2;5142:18;;5129:32;;-1:-1:-1;5208:2:1;5193:18;;;5180:32;;4990:228;-1:-1:-1;;;4990:228:1:o;5223:399::-;;;;;5384:3;5372:9;5363:7;5359:23;5355:33;5352:2;;;5406:6;5398;5391:22;5352:2;5434:29;5453:9;5434:29;:::i;:::-;5424:39;5510:2;5495:18;;5482:32;;-1:-1:-1;5561:2:1;5546:18;;5533:32;;5612:2;5597:18;5584:32;;-1:-1:-1;5342:280:1;-1:-1:-1;;;5342:280:1:o;5627:226::-;5803:42;5791:55;;;;5773:74;;5761:2;5746:18;;5728:125::o;6097:406::-;6317:42;6386:15;;;6368:34;;6438:15;;;;6433:2;6418:18;;6411:43;6485:2;6470:18;;6463:34;;;;6295:2;6280:18;;6262:241::o;6508:305::-;6720:42;6708:55;;;;6690:74;;6795:2;6780:18;;6773:34;6678:2;6663:18;;6645:168::o;6818:776::-;7171:42;7240:15;;;7222:34;;7292:15;;;7287:2;7272:18;;7265:43;7344:15;;;7339:2;7324:18;;7317:43;7391:2;7376:18;;7369:34;;;;7434:3;7419:19;;7412:35;;;;7478:3;7463:19;;7456:35;7528:15;;;7522:3;7507:19;;7500:44;7575:3;7560:19;;7553:35;;;;7148:3;7133:19;;7115:479::o;7599:1192::-;8115:42;8103:55;;;8085:74;;8195:55;;;8190:2;8175:18;;8168:83;8287:55;;;;8282:2;8267:18;;8260:83;8374:2;8359:18;;8352:34;;;;8417:3;8402:19;;8395:35;;;;8461:3;8446:19;;8439:35;;;;8505:3;8490:19;;8483:35;;;;8549:3;8534:19;;8527:35;8593:3;8578:19;;8571:35;8637:3;8622:19;;8615:35;8681:3;8666:19;;8659:36;8726:3;8711:19;;8704:36;;;;8771:3;8756:19;;8749:36;;;;8072:3;8057:19;;8039:752::o;9199:695::-;9524:42;9593:15;;;9575:34;;9645:15;;;9640:2;9625:18;;9618:43;9692:2;9677:18;;9670:34;;;;9735:2;9720:18;;9713:34;;;;9778:3;9763:19;;9756:35;9828:15;;;9822:3;9807:19;;9800:44;9875:3;9860:19;;9853:35;;;;9501:3;9486:19;;9468:426::o;10201:187::-;10366:14;;10359:22;10341:41;;10329:2;10314:18;;10296:92::o;10393:345::-;10595:2;10577:21;;;10634:2;10614:18;;;10607:30;10673:23;10668:2;10653:18;;10646:51;10729:2;10714:18;;10567:171::o;10743:398::-;10945:2;10927:21;;;10984:2;10964:18;;;10957:30;11023:34;11018:2;11003:18;;10996:62;11094:4;11089:2;11074:18;;11067:32;11131:3;11116:19;;10917:224::o;11146:400::-;11348:2;11330:21;;;11387:2;11367:18;;;11360:30;11426:34;11421:2;11406:18;;11399:62;11497:6;11492:2;11477:18;;11470:34;11536:3;11521:19;;11320:226::o;11551:351::-;11753:2;11735:21;;;11792:2;11772:18;;;11765:30;11831:29;11826:2;11811:18;;11804:57;11893:2;11878:18;;11725:177::o;11907:344::-;12109:2;12091:21;;;12148:2;12128:18;;;12121:30;12187:22;12182:2;12167:18;;12160:50;12242:2;12227:18;;12081:170::o;12256:404::-;12458:2;12440:21;;;12497:2;12477:18;;;12470:30;12536:34;12531:2;12516:18;;12509:62;12607:10;12602:2;12587:18;;12580:38;12650:3;12635:19;;12430:230::o;12665:349::-;12867:2;12849:21;;;12906:2;12886:18;;;12879:30;12945:27;12940:2;12925:18;;12918:55;13005:2;12990:18;;12839:175::o;13019:344::-;13221:2;13203:21;;;13260:2;13240:18;;;13233:30;13299:22;13294:2;13279:18;;13272:50;13354:2;13339:18;;13193:170::o;13368:403::-;13570:2;13552:21;;;13609:2;13589:18;;;13582:30;13648:34;13643:2;13628:18;;13621:62;13719:9;13714:2;13699:18;;13692:37;13761:3;13746:19;;13542:229::o;13776:341::-;13978:2;13960:21;;;14017:2;13997:18;;;13990:30;14056:19;14051:2;14036:18;;14029:47;14108:2;14093:18;;13950:167::o;14122:403::-;14324:2;14306:21;;;14363:2;14343:18;;;14336:30;14402:34;14397:2;14382:18;;14375:62;14473:9;14468:2;14453:18;;14446:37;14515:3;14500:19;;14296:229::o;14530:350::-;14732:2;14714:21;;;14771:2;14751:18;;;14744:30;14810:28;14805:2;14790:18;;14783:56;14871:2;14856:18;;14704:176::o;14885:402::-;15087:2;15069:21;;;15126:2;15106:18;;;15099:30;15165:34;15160:2;15145:18;;15138:62;15236:8;15231:2;15216:18;;15209:36;15277:3;15262:19;;15059:228::o;15292:410::-;15494:2;15476:21;;;15533:2;15513:18;;;15506:30;15572:34;15567:2;15552:18;;15545:62;15643:16;15638:2;15623:18;;15616:44;15692:3;15677:19;;15466:236::o;15707:397::-;15909:2;15891:21;;;15948:2;15928:18;;;15921:30;15987:34;15982:2;15967:18;;15960:62;16058:3;16053:2;16038:18;;16031:31;16094:3;16079:19;;15881:223::o;16109:400::-;16311:2;16293:21;;;16350:2;16330:18;;;16323:30;16389:34;16384:2;16369:18;;16362:62;16460:6;16455:2;16440:18;;16433:34;16499:3;16484:19;;16283:226::o;16514:400::-;16716:2;16698:21;;;16755:2;16735:18;;;16728:30;16794:34;16789:2;16774:18;;16767:62;16865:6;16860:2;16845:18;;16838:34;16904:3;16889:19;;16688:226::o;16919:398::-;17121:2;17103:21;;;17160:2;17140:18;;;17133:30;17199:34;17194:2;17179:18;;17172:62;17270:4;17265:2;17250:18;;17243:32;17307:3;17292:19;;17093:224::o;17322:341::-;17524:2;17506:21;;;17563:2;17543:18;;;17536:30;17602:19;17597:2;17582:18;;17575:47;17654:2;17639:18;;17496:167::o;17668:344::-;17870:2;17852:21;;;17909:2;17889:18;;;17882:30;17948:22;17943:2;17928:18;;17921:50;18003:2;17988:18;;17842:170::o;18017:348::-;18219:2;18201:21;;;18258:2;18238:18;;;18231:30;18297:26;18292:2;18277:18;;18270:54;18356:2;18341:18;;18191:174::o;18370:177::-;18516:25;;;18504:2;18489:18;;18471:76::o;18552:248::-;18726:25;;;18782:2;18767:18;;18760:34;18714:2;18699:18;;18681:119::o;18805:319::-;19007:25;;;19063:2;19048:18;;19041:34;;;;19106:2;19091:18;;19084:34;18995:2;18980:18;;18962:162::o;19129:463::-;19388:25;;;19444:2;19429:18;;19422:34;;;;19487:2;19472:18;;19465:34;;;;19530:2;19515:18;;19508:34;19573:3;19558:19;;19551:35;19375:3;19360:19;;19342:250::o

Swarm Source

ipfs://cc61c989077f5ccc64e8214e4583bf3c9d48d510812103a4013648f227694ce2

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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

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