Contract 0xaE8bC96DA4F9A9613c323478BE181FDb2Aa0E1BF 1

 

Contract Overview

mStable: Staking 1.0
Balance:
0 Ether

EtherValue:
$0.00

Token:
 
Txn Hash
Method
Block
From
To
Value
0x3a7e59d0e13731faa4fb5406c098bcbab2e5e572252409836a19e03f21289179Exit(pending)2022-08-11 16:40:261 day 1 hr ago0xf661bf5a87c3b8339ff8da98239e156ba87bc73a IN mStable: Staking 1.00 Ether(Pending)(Pending)
0x3b8a395aa04c2548d2bb05cab133e4d3b5c84dd0ae3218a5bd8c1596269ea3a4Exit153049822022-08-09 1:07:083 days 17 hrs ago0x64e445811e1ec6e1ed781789486a9e5a541ca240 IN  mStable: Staking 1.00 Ether0.‍00183406 13
0xf414e9568381d5b33e27e1e142db11927b0308ec018afe629bd00b535d993c02Exit152368712022-07-29 10:36:4814 days 7 hrs ago0x82da1f1d1dbae51563a9c469c2d0969d769b2ef4 IN  mStable: Staking 1.00 Ether0.‍00111265 8
0x4242193b03593086670fbeeeff611b2e9259a85ce910ced3ce47cd789dc4ad48Claim Reward151706642022-07-19 3:31:0024 days 14 hrs ago0x0ea4a285e1353f490ec7f473ab3174cac71cf79a IN  mStable: Staking 1.00 Ether0.‍00275485 29.‍67700303
0xb2abaa92fd06b6169413c0a77e65f1888a512ec6bd65f0f0b850e9df8b7a51aaClaim Reward151190312022-07-11 3:49:3732 days 14 hrs ago0xf1a5161d604d7348d7f5c534517b5404a8edefe4 IN  mStable: Staking 1.00 Ether0.‍00330448 45
0xd2216e5b8b34bf11248ffac8883ac815ba1275fd604e83489d9d8bec57ec8c23Exit151075952022-07-09 9:38:1934 days 8 hrs agoENS Name nygenit.eth IN  mStable: Staking 1.00 Ether0.‍00168631 12
0x0d32f6edff193865874b5b22c905df7890365951679a360ef1f9edf2a3723c73Exit151073862022-07-09 8:46:0034 days 9 hrs ago0xc286d8c19adb24f7d640edb0f74d9c480776ec0b IN  mStable: Staking 1.00 Ether0.‍00112523 9
0x5ebd1d59bffafd085561ffb9aafffed43fb88befa3034086f1d3ad61359945f1Exit150673542022-07-03 4:13:1640 days 14 hrs agoENS Name lkcho.eth IN  mStable: Staking 1.00 Ether0.‍0010002 8
0x813326504b9f924b73011b417526abd3fb693b06d6b6f4d97f287fdc1f64afc3Exit150310482022-06-26 21:47:0446 days 20 hrs ago0x4b69c929edc7b8b911e4309e1fecb7e9c1ded9ef IN  mStable: Staking 1.00 Ether0.‍0038092127
0x40c1757236c34d42a91ff29562a7920e9832e340076f0b61a0d4cb670611a622Exit149921982022-06-19 18:27:0554 days 3 mins ago0x3938c28aaa4bcb0b20f0c0c8e25750b1610e47b3 IN  mStable: Staking 1.00 Ether0.‍00236703 19
0x147d4f70a83cf5d416b0b595912d9690462597b1b7dc6d44758782a881ee9adfExit148895182022-06-02 6:49:4371 days 11 hrs ago0x8da17bbb1456d3839ac6a6fe64607769e0c85140 IN  mStable: Staking 1.00 Ether0.‍00382458 41.‍32814903
0x1cfee97a5252e770364f4b0b890b4a334c0f8e0ccd0be769a9ad4f4e8ac85723Claim Reward148895022022-06-02 6:44:5271 days 11 hrs ago0x8da17bbb1456d3839ac6a6fe64607769e0c85140 IN  mStable: Staking 1.00 Ether0.‍00503587 47.‍08931317
0x6c721f0725a291da59e1f83e51727ed1e4618bab7e806b4ca8b0f12e83fb5031Exit148893882022-06-02 6:18:2071 days 12 hrs agoENS Name debanker.eth IN  mStable: Staking 1.00 Ether0.‍0058284448
0xf61027c03dc2e5c88383c2ab9af4872f9ee6643e88950bf8af1cf91424ca53ebExit148758202022-05-31 1:04:4173 days 17 hrs agoENS Name cryptonumerist.eth IN  mStable: Staking 1.00 Ether0.‍00395029 28
0x29c27261cb322a1360f53b50b43d955bacb1dd77be7cacfecc14554050f28c42Exit148657732022-05-29 9:43:0075 days 8 hrs ago0x3ee89c93c1beb2bddb5fe6de5026cdf5dd1a369a IN  mStable: Staking 1.00 Ether0.‍00196736 14
0x87e1e53fa6c326b98d9a4b6c4c4ea754f6220b24808a915b980f0df447ac09f1Exit148491122022-05-26 16:53:2178 days 1 hr ago0x4bb7fba588b4254536de4316e8fb346bbe275ecb IN  mStable: Staking 1.00 Ether0.‍01001682 71
0x44e1d907bade9c537f4fb0dabda295a14caad18bc39f2205aca51ccdd9bf7548Exit146351152022-04-22 14:05:35112 days 4 hrs ago0x365595ab460cb664c77d4e038c9051f09d781065 IN  mStable: Staking 1.00 Ether0.‍00169996 14
0x725ee2efe0af3096684d42aad07b882780621200f7aceb022573ea11c628f9f1Exit145962032022-04-16 11:56:51118 days 6 hrs ago0x57bd6eca6619f19cb486e696f0dd0b4d1d56a12f IN  mStable: Staking 1.00 Ether0.‍00210442 16.‍83187945
0xcc696b59afead018eb28d7b74368ba26d0a83a3cc0cada4360673a2f971046d2Claim Reward145810832022-04-14 3:16:03120 days 15 hrs ago0x7e1fc55d416676998043b4b766968fb0ec8c7550 IN  mStable: Staking 1.00 Ether0.‍00264654 29.‍23287677
0x897bb1085a5cf0b4a1fbb102b141dde8878e279809b91c68785a67b483ceb9baExit145698892022-04-12 9:18:03122 days 9 hrs ago0x815612815d7fb01b1e8a97fe4a0996e77245a3aa IN  mStable: Staking 1.00 Ether0.‍00451462 32
0x1bec8d645d5e494d31fa08f8086700217ee6d546287f58221f27d04d653866d5Exit145611602022-04-11 0:27:56123 days 18 hrs agoENS Name desker.eth IN  mStable: Staking 1.00 Ether0.‍00195171 16
0x27909578cc2e872b1a79dbd7559f0806be427bf8f24b27ec31ae0d2ed1258116Exit145112412022-04-03 5:06:22131 days 13 hrs ago0xb932936d43f30fdc782074b20bb9f73f4e6787cc IN  mStable: Staking 1.00 Ether0.‍00388318 34.‍87493776
0xb122a7443f3b49d5dff7d50de1c74931de7b2ff918569f9cbf1440ee375d8631Exit144834132022-03-29 21:00:19135 days 21 hrs agoENS Name digitalego.eth IN  mStable: Staking 1.00 Ether0.‍0030538833
0x4306782649a8e6b628321051179b33c38aff2b3e58a886a540d28f820fb55938Claim Reward144834132022-03-29 21:00:19135 days 21 hrs agoENS Name digitalego.eth IN  mStable: Staking 1.00 Ether0.‍0040934133
0x75271ea24c6814e44be761e7f8a3cb2023e07ce70a840a8d15d210a9ca9bf252Exit144720092022-03-28 2:29:49137 days 16 hrs ago0x9f56977082b76b956cd93500783047990b033e29 IN  mStable: Staking 1.00 Ether0.‍00586789 41.‍75664853
[ Download CSV Export 
View more zero value Internal Transactions in Advanced View mode
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
IncentivisedVotingLockup

Compiler Version
v0.5.16+commit.9c3226ce

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, GNU AGPLv3 license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2020-09-25
*/

pragma solidity 0.5.16;


interface IBasicToken {
    function decimals() external view returns (uint8);
}

contract IERC20WithCheckpointing {
    function balanceOf(address _owner) public view returns (uint256);
    function balanceOfAt(address _owner, uint256 _blockNumber) public view returns (uint256);

    function totalSupply() public view returns (uint256);
    function totalSupplyAt(uint256 _blockNumber) public view returns (uint256);
}

contract IIncentivisedVotingLockup is IERC20WithCheckpointing {

    function getLastUserPoint(address _addr) external view returns(int128 bias, int128 slope, uint256 ts);
    function createLock(uint256 _value, uint256 _unlockTime) external;
    function withdraw() external;
    function increaseLockAmount(uint256 _value) external;
    function increaseLockLength(uint256 _unlockTime) external;
    function eject(address _user) external;
    function expireContract() external;

    function claimReward() public;
    function earned(address _account) public view returns (uint256);
}

contract ReentrancyGuard {
    bool private _notEntered;

    constructor () internal {
        // Storing an initial non-zero value makes deployment a bit more
        // expensive, but in exchange the refund on every call to nonReentrant
        // will be lower in amount. Since refunds are capped to a percetange of
        // the total transaction's gas, it is best to keep them low in cases
        // like this one, to increase the likelihood of the full refund coming
        // into effect.
        _notEntered = true;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_notEntered, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _notEntered = false;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _notEntered = true;
    }
}

contract ModuleKeys {

    // Governance
    // ===========
                                                // Phases
    // keccak256("Governance");                 // 2.x
    bytes32 internal constant KEY_GOVERNANCE = 0x9409903de1e6fd852dfc61c9dacb48196c48535b60e25abf92acc92dd689078d;
    //keccak256("Staking");                     // 1.2
    bytes32 internal constant KEY_STAKING = 0x1df41cd916959d1163dc8f0671a666ea8a3e434c13e40faef527133b5d167034;
    //keccak256("ProxyAdmin");                  // 1.0
    bytes32 internal constant KEY_PROXY_ADMIN = 0x96ed0203eb7e975a4cbcaa23951943fa35c5d8288117d50c12b3d48b0fab48d1;

    // mStable
    // =======
    // keccak256("OracleHub");                  // 1.2
    bytes32 internal constant KEY_ORACLE_HUB = 0x8ae3a082c61a7379e2280f3356a5131507d9829d222d853bfa7c9fe1200dd040;
    // keccak256("Manager");                    // 1.2
    bytes32 internal constant KEY_MANAGER = 0x6d439300980e333f0256d64be2c9f67e86f4493ce25f82498d6db7f4be3d9e6f;
    //keccak256("Recollateraliser");            // 2.x
    bytes32 internal constant KEY_RECOLLATERALISER = 0x39e3ed1fc335ce346a8cbe3e64dd525cf22b37f1e2104a755e761c3c1eb4734f;
    //keccak256("MetaToken");                   // 1.1
    bytes32 internal constant KEY_META_TOKEN = 0xea7469b14936af748ee93c53b2fe510b9928edbdccac3963321efca7eb1a57a2;
    // keccak256("SavingsManager");             // 1.0
    bytes32 internal constant KEY_SAVINGS_MANAGER = 0x12fe936c77a1e196473c4314f3bed8eeac1d757b319abb85bdda70df35511bf1;
}

interface INexus {
    function governor() external view returns (address);
    function getModule(bytes32 key) external view returns (address);

    function proposeModule(bytes32 _key, address _addr) external;
    function cancelProposedModule(bytes32 _key) external;
    function acceptProposedModule(bytes32 _key) external;
    function acceptProposedModules(bytes32[] calldata _keys) external;

    function requestLockModule(bytes32 _key) external;
    function cancelLockModule(bytes32 _key) external;
    function lockModule(bytes32 _key) external;
}

contract Module is ModuleKeys {

    INexus public nexus;

    /**
     * @dev Initialises the Module by setting publisher addresses,
     *      and reading all available system module information
     */
    constructor(address _nexus) internal {
        require(_nexus != address(0), "Nexus is zero address");
        nexus = INexus(_nexus);
    }

    /**
     * @dev Modifier to allow function calls only from the Governor.
     */
    modifier onlyGovernor() {
        require(msg.sender == _governor(), "Only governor can execute");
        _;
    }

    /**
     * @dev Modifier to allow function calls only from the Governance.
     *      Governance is either Governor address or Governance address.
     */
    modifier onlyGovernance() {
        require(
            msg.sender == _governor() || msg.sender == _governance(),
            "Only governance can execute"
        );
        _;
    }

    /**
     * @dev Modifier to allow function calls only from the ProxyAdmin.
     */
    modifier onlyProxyAdmin() {
        require(
            msg.sender == _proxyAdmin(), "Only ProxyAdmin can execute"
        );
        _;
    }

    /**
     * @dev Modifier to allow function calls only from the Manager.
     */
    modifier onlyManager() {
        require(msg.sender == _manager(), "Only manager can execute");
        _;
    }

    /**
     * @dev Returns Governor address from the Nexus
     * @return Address of Governor Contract
     */
    function _governor() internal view returns (address) {
        return nexus.governor();
    }

    /**
     * @dev Returns Governance Module address from the Nexus
     * @return Address of the Governance (Phase 2)
     */
    function _governance() internal view returns (address) {
        return nexus.getModule(KEY_GOVERNANCE);
    }

    /**
     * @dev Return Staking Module address from the Nexus
     * @return Address of the Staking Module contract
     */
    function _staking() internal view returns (address) {
        return nexus.getModule(KEY_STAKING);
    }

    /**
     * @dev Return ProxyAdmin Module address from the Nexus
     * @return Address of the ProxyAdmin Module contract
     */
    function _proxyAdmin() internal view returns (address) {
        return nexus.getModule(KEY_PROXY_ADMIN);
    }

    /**
     * @dev Return MetaToken Module address from the Nexus
     * @return Address of the MetaToken Module contract
     */
    function _metaToken() internal view returns (address) {
        return nexus.getModule(KEY_META_TOKEN);
    }

    /**
     * @dev Return OracleHub Module address from the Nexus
     * @return Address of the OracleHub Module contract
     */
    function _oracleHub() internal view returns (address) {
        return nexus.getModule(KEY_ORACLE_HUB);
    }

    /**
     * @dev Return Manager Module address from the Nexus
     * @return Address of the Manager Module contract
     */
    function _manager() internal view returns (address) {
        return nexus.getModule(KEY_MANAGER);
    }

    /**
     * @dev Return SavingsManager Module address from the Nexus
     * @return Address of the SavingsManager Module contract
     */
    function _savingsManager() internal view returns (address) {
        return nexus.getModule(KEY_SAVINGS_MANAGER);
    }

    /**
     * @dev Return Recollateraliser Module address from the Nexus
     * @return  Address of the Recollateraliser Module contract (Phase 2)
     */
    function _recollateraliser() internal view returns (address) {
        return nexus.getModule(KEY_RECOLLATERALISER);
    }
}

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

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

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

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

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

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

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

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

interface IRewardsDistributionRecipient {
    function notifyRewardAmount(uint256 reward) external;
    function getRewardToken() external view returns (IERC20);
}

contract RewardsDistributionRecipient is IRewardsDistributionRecipient, Module {

    // @abstract
    function notifyRewardAmount(uint256 reward) external;
    function getRewardToken() external view returns (IERC20);

    // This address has the ability to distribute the rewards
    address public rewardsDistributor;

    /** @dev Recipient is a module, governed by mStable governance */
    constructor(address _nexus, address _rewardsDistributor)
        internal
        Module(_nexus)
    {
        rewardsDistributor = _rewardsDistributor;
    }

    /**
     * @dev Only the rewards distributor can notify about rewards
     */
    modifier onlyRewardsDistributor() {
        require(msg.sender == rewardsDistributor, "Caller is not reward distributor");
        _;
    }

    /**
     * @dev Change the rewardsDistributor - only called by mStable governor
     * @param _rewardsDistributor   Address of the new distributor
     */
    function setRewardsDistribution(address _rewardsDistributor)
        external
        onlyGovernor
    {
        rewardsDistributor = _rewardsDistributor;
    }
}

/**
 * @dev Interface of the ERC20 standard as defined in the EIP. Does not include
 * the optional functions; to access them see {ERC20Detailed}.
 */

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

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

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     *
     * _Available since v2.4.0._
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

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

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     *
     * _Available since v2.4.0._
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

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

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     *
     * _Available since v2.4.0._
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following 
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // According to EIP-1052, 0x0 is the value returned for not-yet created accounts
        // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
        // for accounts without code, i.e. `keccak256('')`
        bytes32 codehash;
        bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
        // solhint-disable-next-line no-inline-assembly
        assembly { codehash := extcodehash(account) }
        return (codehash != accountHash && codehash != 0x0);
    }

    /**
     * @dev Converts an `address` into `address payable`. Note that this is
     * simply a type cast: the actual underlying value is not changed.
     *
     * _Available since v2.4.0._
     */
    function toPayable(address account) internal pure returns (address payable) {
        return address(uint160(account));
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     *
     * _Available since v2.4.0._
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        // solhint-disable-next-line avoid-call-value
        (bool success, ) = recipient.call.value(amount)("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }
}

library SafeERC20 {
    using SafeMath for uint256;
    using Address for address;

    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    function safeApprove(IERC20 token, address spender, uint256 value) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        // solhint-disable-next-line max-line-length
        require((value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).add(value);
        callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
        callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves.

        // A Solidity high level call has three parts:
        //  1. The target address is checked to verify it contains contract code
        //  2. The call itself is made, and success asserted
        //  3. The return value is decoded, which in turn checks the size of the returned data.
        // solhint-disable-next-line max-line-length
        require(address(token).isContract(), "SafeERC20: call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = address(token).call(data);
        require(success, "SafeERC20: low-level call failed");

        if (returndata.length > 0) { // Return data is optional
            // solhint-disable-next-line max-line-length
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

library SignedSafeMath128 {
    int128 constant private _INT128_MIN = -2**127;

    /**
     * @dev Returns the multiplication of two signed integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(int128 a, int128 b) internal pure returns (int128) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        require(!(a == -1 && b == _INT128_MIN), "SignedSafeMath: multiplication overflow");

        int128 c = a * b;
        require(c / a == b, "SignedSafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two signed integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(int128 a, int128 b) internal pure returns (int128) {
        require(b != 0, "SignedSafeMath: division by zero");
        require(!(b == -1 && a == _INT128_MIN), "SignedSafeMath: division overflow");

        int128 c = a / b;

        return c;
    }

    /**
     * @dev Returns the subtraction of two signed integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(int128 a, int128 b) internal pure returns (int128) {
        int128 c = a - b;
        require((b >= 0 && c <= a) || (b < 0 && c > a), "SignedSafeMath: subtraction overflow");

        return c;
    }

    /**
     * @dev Returns the addition of two signed integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(int128 a, int128 b) internal pure returns (int128) {
        int128 c = a + b;
        require((b >= 0 && c >= a) || (b < 0 && c < a), "SignedSafeMath: addition overflow");

        return c;
    }
}

library StableMath {

    using SafeMath for uint256;

    /**
     * @dev Scaling unit for use in specific calculations,
     * where 1 * 10**18, or 1e18 represents a unit '1'
     */
    uint256 private constant FULL_SCALE = 1e18;

    /**
     * @notice Token Ratios are used when converting between units of bAsset, mAsset and MTA
     * Reasoning: Takes into account token decimals, and difference in base unit (i.e. grams to Troy oz for gold)
     * @dev bAsset ratio unit for use in exact calculations,
     * where (1 bAsset unit * bAsset.ratio) / ratioScale == x mAsset unit
     */
    uint256 private constant RATIO_SCALE = 1e8;

    /**
     * @dev Provides an interface to the scaling unit
     * @return Scaling unit (1e18 or 1 * 10**18)
     */
    function getFullScale() internal pure returns (uint256) {
        return FULL_SCALE;
    }

    /**
     * @dev Provides an interface to the ratio unit
     * @return Ratio scale unit (1e8 or 1 * 10**8)
     */
    function getRatioScale() internal pure returns (uint256) {
        return RATIO_SCALE;
    }

    /**
     * @dev Scales a given integer to the power of the full scale.
     * @param x   Simple uint256 to scale
     * @return    Scaled value a to an exact number
     */
    function scaleInteger(uint256 x)
        internal
        pure
        returns (uint256)
    {
        return x.mul(FULL_SCALE);
    }

    /***************************************
              PRECISE ARITHMETIC
    ****************************************/

    /**
     * @dev Multiplies two precise units, and then truncates by the full scale
     * @param x     Left hand input to multiplication
     * @param y     Right hand input to multiplication
     * @return      Result after multiplying the two inputs and then dividing by the shared
     *              scale unit
     */
    function mulTruncate(uint256 x, uint256 y)
        internal
        pure
        returns (uint256)
    {
        return mulTruncateScale(x, y, FULL_SCALE);
    }

    /**
     * @dev Multiplies two precise units, and then truncates by the given scale. For example,
     * when calculating 90% of 10e18, (10e18 * 9e17) / 1e18 = (9e36) / 1e18 = 9e18
     * @param x     Left hand input to multiplication
     * @param y     Right hand input to multiplication
     * @param scale Scale unit
     * @return      Result after multiplying the two inputs and then dividing by the shared
     *              scale unit
     */
    function mulTruncateScale(uint256 x, uint256 y, uint256 scale)
        internal
        pure
        returns (uint256)
    {
        // e.g. assume scale = fullScale
        // z = 10e18 * 9e17 = 9e36
        uint256 z = x.mul(y);
        // return 9e38 / 1e18 = 9e18
        return z.div(scale);
    }

    /**
     * @dev Multiplies two precise units, and then truncates by the full scale, rounding up the result
     * @param x     Left hand input to multiplication
     * @param y     Right hand input to multiplication
     * @return      Result after multiplying the two inputs and then dividing by the shared
     *              scale unit, rounded up to the closest base unit.
     */
    function mulTruncateCeil(uint256 x, uint256 y)
        internal
        pure
        returns (uint256)
    {
        // e.g. 8e17 * 17268172638 = 138145381104e17
        uint256 scaled = x.mul(y);
        // e.g. 138145381104e17 + 9.99...e17 = 138145381113.99...e17
        uint256 ceil = scaled.add(FULL_SCALE.sub(1));
        // e.g. 13814538111.399...e18 / 1e18 = 13814538111
        return ceil.div(FULL_SCALE);
    }

    /**
     * @dev Precisely divides two units, by first scaling the left hand operand. Useful
     *      for finding percentage weightings, i.e. 8e18/10e18 = 80% (or 8e17)
     * @param x     Left hand input to division
     * @param y     Right hand input to division
     * @return      Result after multiplying the left operand by the scale, and
     *              executing the division on the right hand input.
     */
    function divPrecisely(uint256 x, uint256 y)
        internal
        pure
        returns (uint256)
    {
        // e.g. 8e18 * 1e18 = 8e36
        uint256 z = x.mul(FULL_SCALE);
        // e.g. 8e36 / 10e18 = 8e17
        return z.div(y);
    }


    /***************************************
                  RATIO FUNCS
    ****************************************/

    /**
     * @dev Multiplies and truncates a token ratio, essentially flooring the result
     *      i.e. How much mAsset is this bAsset worth?
     * @param x     Left hand operand to multiplication (i.e Exact quantity)
     * @param ratio bAsset ratio
     * @return      Result after multiplying the two inputs and then dividing by the ratio scale
     */
    function mulRatioTruncate(uint256 x, uint256 ratio)
        internal
        pure
        returns (uint256 c)
    {
        return mulTruncateScale(x, ratio, RATIO_SCALE);
    }

    /**
     * @dev Multiplies and truncates a token ratio, rounding up the result
     *      i.e. How much mAsset is this bAsset worth?
     * @param x     Left hand input to multiplication (i.e Exact quantity)
     * @param ratio bAsset ratio
     * @return      Result after multiplying the two inputs and then dividing by the shared
     *              ratio scale, rounded up to the closest base unit.
     */
    function mulRatioTruncateCeil(uint256 x, uint256 ratio)
        internal
        pure
        returns (uint256)
    {
        // e.g. How much mAsset should I burn for this bAsset (x)?
        // 1e18 * 1e8 = 1e26
        uint256 scaled = x.mul(ratio);
        // 1e26 + 9.99e7 = 100..00.999e8
        uint256 ceil = scaled.add(RATIO_SCALE.sub(1));
        // return 100..00.999e8 / 1e8 = 1e18
        return ceil.div(RATIO_SCALE);
    }


    /**
     * @dev Precisely divides two ratioed units, by first scaling the left hand operand
     *      i.e. How much bAsset is this mAsset worth?
     * @param x     Left hand operand in division
     * @param ratio bAsset ratio
     * @return      Result after multiplying the left operand by the scale, and
     *              executing the division on the right hand input.
     */
    function divRatioPrecisely(uint256 x, uint256 ratio)
        internal
        pure
        returns (uint256 c)
    {
        // e.g. 1e14 * 1e8 = 1e22
        uint256 y = x.mul(RATIO_SCALE);
        // return 1e22 / 1e12 = 1e10
        return y.div(ratio);
    }

    /***************************************
                    HELPERS
    ****************************************/

    /**
     * @dev Calculates minimum of two numbers
     * @param x     Left hand input
     * @param y     Right hand input
     * @return      Minimum of the two inputs
     */
    function min(uint256 x, uint256 y)
        internal
        pure
        returns (uint256)
    {
        return x > y ? y : x;
    }

    /**
     * @dev Calculated maximum of two numbers
     * @param x     Left hand input
     * @param y     Right hand input
     * @return      Maximum of the two inputs
     */
    function max(uint256 x, uint256 y)
        internal
        pure
        returns (uint256)
    {
        return x > y ? x : y;
    }

    /**
     * @dev Clamps a value to an upper bound
     * @param x           Left hand input
     * @param upperBound  Maximum possible value to return
     * @return            Input x clamped to a maximum value, upperBound
     */
    function clamp(uint256 x, uint256 upperBound)
        internal
        pure
        returns (uint256)
    {
        return x > upperBound ? upperBound : x;
    }
}

library Root {

    using SafeMath for uint256;

    /**
     * @dev Returns the square root of a given number
     * @param x Input
     * @return y Square root of Input
     */
    function sqrt(uint x) internal pure returns (uint y) {
        uint z = (x.add(1)).div(2);
        y = x;
        while (z < y) {
            y = z;
            z = (x.div(z).add(z)).div(2);
        }
    }
}

/* solium-disable security/no-block-members */
/**
 * @title  IncentivisedVotingLockup
 * @author Voting Weight tracking & Decay
 *             -> Curve Finance (MIT) - forked & ported to Solidity
 *             -> https://github.com/curvefi/curve-dao-contracts/blob/master/contracts/VotingEscrow.vy
 *         osolmaz - Research & Reward distributions
 *         alsco77 - Solidity implementation
 * @notice Lockup MTA, receive vMTA (voting weight that decays over time), and earn
 *         rewards based on staticWeight
 * @dev    Supports:
 *            1) Tracking MTA Locked up (LockedBalance)
 *            2) Pull Based Reward allocations based on Lockup (Static Balance)
 *            3) Decaying voting weight lookup through CheckpointedERC20 (balanceOf)
 *            4) Ejecting fully decayed participants from reward allocation (eject)
 *            5) Migration of points to v2 (used as multiplier in future) ***** (rewardsPaid)
 *            6) Closure of contract (expire)
 */
contract IncentivisedVotingLockup is
    IIncentivisedVotingLockup,
    ReentrancyGuard,
    RewardsDistributionRecipient
{
    using StableMath for uint256;
    using SafeMath for uint256;
    using SignedSafeMath128 for int128;
    using SafeERC20 for IERC20;

    /** Shared Events */
    event Deposit(address indexed provider, uint256 value, uint256 locktime, LockAction indexed action, uint256 ts);
    event Withdraw(address indexed provider, uint256 value, uint256 ts);
    event Ejected(address indexed ejected, address ejector, uint256 ts);
    event Expired();
    event RewardAdded(uint256 reward);
    event RewardPaid(address indexed user, uint256 reward);

    /** Shared Globals */
    IERC20 public stakingToken;
    uint256 private constant WEEK = 7 days;
    uint256 public constant MAXTIME = 365 days;
    uint256 public END;
    bool public expired = false;

    /** Lockup */
    uint256 public globalEpoch;
    Point[] public pointHistory;
    mapping(address => Point[]) public userPointHistory;
    mapping(address => uint256) public userPointEpoch;
    mapping(uint256 => int128) public slopeChanges;
    mapping(address => LockedBalance) public locked;

    // Voting token - Checkpointed view only ERC20
    string public name;
    string public symbol;
    uint256 public decimals = 18;

    /** Rewards */
    // Updated upon admin deposit
    uint256 public periodFinish = 0;
    uint256 public rewardRate = 0;

    // Globals updated per stake/deposit/withdrawal
    uint256 public totalStaticWeight = 0;
    uint256 public lastUpdateTime = 0;
    uint256 public rewardPerTokenStored = 0;

    // Per user storage updated per stake/deposit/withdrawal
    mapping(address => uint256) public userRewardPerTokenPaid;
    mapping(address => uint256) public rewards;
    mapping(address => uint256) public rewardsPaid;

    /** Structs */
    struct Point {
        int128 bias;
        int128 slope;
        uint256 ts;
        uint256 blk;
    }

    struct LockedBalance {
        int128 amount;
        uint256 end;
    }

    enum LockAction {
        CREATE_LOCK,
        INCREASE_LOCK_AMOUNT,
        INCREASE_LOCK_TIME
    }

    constructor(
        address _stakingToken,
        string memory _name,
        string memory _symbol,
        address _nexus,
        address _rewardsDistributor
    )
        public
        RewardsDistributionRecipient(_nexus, _rewardsDistributor)
    {
        stakingToken = IERC20(_stakingToken);
        Point memory init = Point({ bias: int128(0), slope: int128(0), ts: block.timestamp, blk: block.number});
        pointHistory.push(init);

        decimals = IBasicToken(_stakingToken).decimals();
        require(decimals <= 18, "Cannot have more than 18 decimals");

        name = _name;
        symbol = _symbol;

        END = block.timestamp.add(MAXTIME);
    }

    /** @dev Modifier to ensure contract has not yet expired */
    modifier contractNotExpired(){
        require(!expired, "Contract is expired");
        _;
    }

    /**
    * @dev Validates that the user has an expired lock && they still have capacity to earn
    * @param _addr User address to check
    */
    modifier lockupIsOver(address _addr) {
        LockedBalance memory userLock = locked[_addr];
        require(userLock.amount > 0 && block.timestamp >= userLock.end, "Users lock didn't expire");
        require(staticBalanceOf(_addr) > 0, "User must have existing bias");
        _;
    }

    /***************************************
                LOCKUP - GETTERS
    ****************************************/

    /**
     * @dev Gets the last available user point
     * @param _addr User address
     * @return bias i.e. y
     * @return slope i.e. linear gradient
     * @return ts i.e. time point was logged
     */
    function getLastUserPoint(address _addr)
        external
        view
        returns(
            int128 bias,
            int128 slope,
            uint256 ts
        )
    {
        uint256 uepoch = userPointEpoch[_addr];
        if(uepoch == 0){
            return (0, 0, 0);
        }
        Point memory point = userPointHistory[_addr][uepoch];
        return (point.bias, point.slope, point.ts);
    }

    /***************************************
                    LOCKUP
    ****************************************/

    /**
     * @dev Records a checkpoint of both individual and global slope
     * @param _addr User address, or address(0) for only global
     * @param _oldLocked Old amount that user had locked, or null for global
     * @param _newLocked new amount that user has locked, or null for global
     */
    function _checkpoint(
        address _addr,
        LockedBalance memory _oldLocked,
        LockedBalance memory _newLocked
    )
        internal
    {
        Point memory userOldPoint;
        Point memory userNewPoint;
        int128 oldSlopeDelta = 0;
        int128 newSlopeDelta = 0;
        uint256 epoch = globalEpoch;

        if(_addr != address(0)){
            // Calculate slopes and biases
            // Kept at zero when they have to
            if(_oldLocked.end > block.timestamp && _oldLocked.amount > 0){
                userOldPoint.slope = _oldLocked.amount.div(int128(MAXTIME));
                userOldPoint.bias = userOldPoint.slope.mul(int128(_oldLocked.end.sub(block.timestamp)));
            }
            if(_newLocked.end > block.timestamp && _newLocked.amount > 0){
                userNewPoint.slope = _newLocked.amount.div(int128(MAXTIME));
                userNewPoint.bias = userNewPoint.slope.mul(int128(_newLocked.end.sub(block.timestamp)));
            }

            // Moved from bottom final if statement to resolve stack too deep err
            // start {
            // Now handle user history
            uint256 uEpoch = userPointEpoch[_addr];
            if(uEpoch == 0){
                userPointHistory[_addr].push(userOldPoint);
            }
            // track the total static weight
            uint256 newStatic = _staticBalance(userNewPoint.slope, block.timestamp, _newLocked.end);
            uint256 additiveStaticWeight = totalStaticWeight.add(newStatic);
            if(uEpoch > 0){
                uint256 oldStatic = _staticBalance(userPointHistory[_addr][uEpoch].slope, userPointHistory[_addr][uEpoch].ts, _oldLocked.end);
                additiveStaticWeight = additiveStaticWeight.sub(oldStatic);
            }
            totalStaticWeight = additiveStaticWeight;

            userPointEpoch[_addr] = uEpoch.add(1);
            userNewPoint.ts = block.timestamp;
            userNewPoint.blk = block.number;
            // userPointHistory[_addr][uEpoch.add(1)] = userNewPoint;
            userPointHistory[_addr].push(userNewPoint);

            // } end

            // Read values of scheduled changes in the slope
            // oldLocked.end can be in the past and in the future
            // newLocked.end can ONLY by in the FUTURE unless everything expired: than zeros
            oldSlopeDelta = slopeChanges[_oldLocked.end];
            if(_newLocked.end != 0){
                if (_newLocked.end == _oldLocked.end) {
                    newSlopeDelta = oldSlopeDelta;
                } else {
                    newSlopeDelta = slopeChanges[_newLocked.end];
                }
            }
        }

        Point memory lastPoint = Point({bias: 0, slope: 0, ts: block.timestamp, blk: block.number});
        if(epoch > 0){
            lastPoint = pointHistory[epoch];
        }
        uint256 lastCheckpoint = lastPoint.ts;

        // initialLastPoint is used for extrapolation to calculate block number
        // (approximately, for *At methods) and save them
        // as we cannot figure that out exactly from inside the contract
        Point memory initialLastPoint = Point({bias: 0, slope: 0, ts: lastPoint.ts, blk: lastPoint.blk});
        uint256 blockSlope = 0; // dblock/dt
        if(block.timestamp > lastPoint.ts){
            blockSlope = StableMath.scaleInteger(block.number.sub(lastPoint.blk)).div(block.timestamp.sub(lastPoint.ts));
        }
        // If last point is already recorded in this block, slope=0
        // But that's ok b/c we know the block in such case

        // Go over weeks to fill history and calculate what the current point is
        uint256 iterativeTime = _floorToWeek(lastCheckpoint);
        for (uint256 i = 0; i < 255; i++){
            // Hopefully it won't happen that this won't get used in 5 years!
            // If it does, users will be able to withdraw but vote weight will be broken
            iterativeTime = iterativeTime.add(WEEK);
            int128 dSlope = 0;
            if(iterativeTime > block.timestamp){
                iterativeTime = block.timestamp;
            } else {
                dSlope = slopeChanges[iterativeTime];
            }
            int128 biasDelta = lastPoint.slope.mul(int128(iterativeTime.sub(lastCheckpoint)));
            lastPoint.bias = lastPoint.bias.sub(biasDelta);
            lastPoint.slope = lastPoint.slope.add(dSlope);
            // This can happen
            if(lastPoint.bias < 0){
                lastPoint.bias = 0;
            }
            // This cannot happen - just in case
            if(lastPoint.slope < 0){
                lastPoint.slope = 0;
            }
            lastCheckpoint = iterativeTime;
            lastPoint.ts = iterativeTime;
            lastPoint.blk = initialLastPoint.blk.add(blockSlope.mulTruncate(iterativeTime.sub(initialLastPoint.ts)));

            // when epoch is incremented, we either push here or after slopes updated below
            epoch = epoch.add(1);
            if(iterativeTime == block.timestamp) {
                lastPoint.blk = block.number;
                break;
            } else {
                // pointHistory[epoch] = lastPoint;
                pointHistory.push(lastPoint);
            }
        }

        globalEpoch = epoch;
        // Now pointHistory is filled until t=now

        if(_addr != address(0)){
            // If last point was in this block, the slope change has been applied already
            // But in such case we have 0 slope(s)
            lastPoint.slope = lastPoint.slope.add(userNewPoint.slope.sub(userOldPoint.slope));
            lastPoint.bias = lastPoint.bias.add(userNewPoint.bias.sub(userOldPoint.bias));
            if(lastPoint.slope < 0) {
                lastPoint.slope = 0;
            }
            if(lastPoint.bias < 0){
                lastPoint.bias = 0;
            }
        }

        // Record the changed point into history
        // pointHistory[epoch] = lastPoint;
        pointHistory.push(lastPoint);

        if(_addr != address(0)){
            // Schedule the slope changes (slope is going down)
            // We subtract new_user_slope from [new_locked.end]
            // and add old_user_slope to [old_locked.end]
            if(_oldLocked.end > block.timestamp){
                // oldSlopeDelta was <something> - userOldPoint.slope, so we cancel that
                oldSlopeDelta = oldSlopeDelta.add(userOldPoint.slope);
                if(_newLocked.end == _oldLocked.end) {
                    oldSlopeDelta = oldSlopeDelta.sub(userNewPoint.slope);  // It was a new deposit, not extension
                }
                slopeChanges[_oldLocked.end] = oldSlopeDelta;
            }
            if(_newLocked.end > block.timestamp) {
                if(_newLocked.end > _oldLocked.end){
                    newSlopeDelta = newSlopeDelta.sub(userNewPoint.slope);  // old slope disappeared at this point
                    slopeChanges[_newLocked.end] = newSlopeDelta;
                }
                // else: we recorded it already in oldSlopeDelta
            }
        }
    }

    /**
     * @dev Deposits or creates a stake for a given address
     * @param _addr User address to assign the stake
     * @param _value Total units of StakingToken to lockup
     * @param _unlockTime Time at which the stake should unlock
     * @param _oldLocked Previous amount staked by this user
     * @param _action See LockAction enum
     */
    function _depositFor(
        address _addr,
        uint256 _value,
        uint256 _unlockTime,
        LockedBalance memory _oldLocked,
        LockAction _action
    )
        internal
    {
        LockedBalance memory newLocked = LockedBalance({amount: _oldLocked.amount, end: _oldLocked.end});

        // Adding to existing lock, or if a lock is expired - creating a new one
        newLocked.amount = newLocked.amount.add(int128(_value));
        if(_unlockTime != 0){
            newLocked.end = _unlockTime;
        }
        locked[_addr] = newLocked;

        // Possibilities:
        // Both _oldLocked.end could be current or expired (>/< block.timestamp)
        // value == 0 (extend lock) or value > 0 (add to lock or extend lock)
        // newLocked.end > block.timestamp (always)
        _checkpoint(_addr, _oldLocked, newLocked);

        if(_value != 0) {
            stakingToken.safeTransferFrom(_addr, address(this), _value);
        }

        emit Deposit(_addr, _value, newLocked.end, _action, block.timestamp);
    }

    /**
     * @dev Public function to trigger global checkpoint
     */
    function checkpoint() external {
        LockedBalance memory empty;
        _checkpoint(address(0), empty, empty);
    }

    /**
     * @dev Creates a new lock
     * @param _value Total units of StakingToken to lockup
     * @param _unlockTime Time at which the stake should unlock
     */
    function createLock(uint256 _value, uint256 _unlockTime)
        external
        nonReentrant
        contractNotExpired
        updateReward(msg.sender)
    {
        uint256 unlock_time = _floorToWeek(_unlockTime);  // Locktime is rounded down to weeks
        LockedBalance memory locked_ = LockedBalance({amount: locked[msg.sender].amount, end: locked[msg.sender].end});

        require(_value > 0, "Must stake non zero amount");
        require(locked_.amount == 0, "Withdraw old tokens first");

        require(unlock_time > block.timestamp, "Can only lock until time in the future");
        require(unlock_time <= END, "Voting lock can be 1 year max (until recol)");

        _depositFor(msg.sender, _value, unlock_time, locked_, LockAction.CREATE_LOCK);
    }

    /**
     * @dev Increases amount of stake thats locked up & resets decay
     * @param _value Additional units of StakingToken to add to exiting stake
     */
    function increaseLockAmount(uint256 _value)
        external
        nonReentrant
        contractNotExpired
        updateReward(msg.sender)
    {
        LockedBalance memory locked_ = LockedBalance({amount: locked[msg.sender].amount, end: locked[msg.sender].end});

        require(_value > 0, "Must stake non zero amount");
        require(locked_.amount > 0, "No existing lock found");
        require(locked_.end > block.timestamp, "Cannot add to expired lock. Withdraw");

        _depositFor(msg.sender, _value, 0, locked_, LockAction.INCREASE_LOCK_AMOUNT);
    }

    /**
     * @dev Increases length of lockup & resets decay
     * @param _unlockTime New unlocktime for lockup
     */
    function increaseLockLength(uint256 _unlockTime)
        external
        nonReentrant
        contractNotExpired
        updateReward(msg.sender)
    {
        LockedBalance memory locked_ = LockedBalance({amount: locked[msg.sender].amount, end: locked[msg.sender].end});
        uint256 unlock_time = _floorToWeek(_unlockTime);  // Locktime is rounded down to weeks

        require(locked_.amount > 0, "Nothing is locked");
        require(locked_.end > block.timestamp, "Lock expired");
        require(unlock_time > locked_.end, "Can only increase lock WEEK");
        require(unlock_time <= END, "Voting lock can be 1 year max (until recol)");

        _depositFor(msg.sender, 0, unlock_time, locked_, LockAction.INCREASE_LOCK_TIME);
    }

    /**
     * @dev Withdraws all the senders stake, providing lockup is over
     */
    function withdraw()
        external
    {
        _withdraw(msg.sender);
    }

    /**
     * @dev Withdraws a given users stake, providing the lockup has finished
     * @param _addr User for which to withdraw
     */
    function _withdraw(address _addr)
        internal
        nonReentrant
        updateReward(_addr)
    {
        LockedBalance memory oldLock = LockedBalance({ end: locked[_addr].end, amount: locked[_addr].amount });
        require(block.timestamp >= oldLock.end || expired, "The lock didn't expire");
        require(oldLock.amount > 0, "Must have something to withdraw");

        uint256 value = uint256(oldLock.amount);

        LockedBalance memory currentLock = LockedBalance({end: 0, amount: 0});
        locked[_addr] = currentLock;

        // oldLocked can have either expired <= timestamp or zero end
        // currentLock has only 0 end
        // Both can have >= 0 amount
        if(!expired){
            _checkpoint(_addr, oldLock, currentLock);
        }

        stakingToken.safeTransfer(_addr, value);

        emit Withdraw(_addr, value, block.timestamp);
    }

    /**
     * @dev Withdraws and consequently claims rewards for the sender
     */
    function exit()
        external
    {
        _withdraw(msg.sender);
        claimReward();
    }

    /**
     * @dev Ejects a user from the reward allocation, given their lock has freshly expired.
     * Leave it to the user to withdraw and claim their rewards.
     * @param _addr Address of the user
     */
    function eject(address _addr)
        external
        contractNotExpired
        lockupIsOver(_addr)
    {
        _withdraw(_addr);

        // solium-disable-next-line security/no-tx-origin
        emit Ejected(_addr, tx.origin, block.timestamp);
    }

    /**
     * @dev Ends the contract, unlocking all stakes.
     * No more staking can happen. Only withdraw and Claim.
     */
    function expireContract()
        external
        onlyGovernor
        contractNotExpired
        updateReward(address(0))
    {
        require(block.timestamp > periodFinish, "Period must be over");

        expired = true;

        emit Expired();
    }



    /***************************************
                    GETTERS
    ****************************************/


    /** @dev Floors a timestamp to the nearest weekly increment */
    function _floorToWeek(uint256 _t)
        internal
        pure
        returns(uint256)
    {
        return _t.div(WEEK).mul(WEEK);
    }

    /**
     * @dev Uses binarysearch to find the most recent point history preceeding block
     * @param _block Find the most recent point history before this block
     * @param _maxEpoch Do not search pointHistories past this index
     */
    function _findBlockEpoch(uint256 _block, uint256 _maxEpoch)
        internal
        view
        returns(uint256)
    {
        // Binary search
        uint256 min = 0;
        uint256 max = _maxEpoch;
        // Will be always enough for 128-bit numbers
        for(uint256 i = 0; i < 128; i++){
            if (min >= max)
                break;
            uint256 mid = (min.add(max).add(1)).div(2);
            if (pointHistory[mid].blk <= _block){
                min = mid;
            } else {
                max = mid.sub(1);
            }
        }
        return min;
    }

    /**
     * @dev Uses binarysearch to find the most recent user point history preceeding block
     * @param _addr User for which to search
     * @param _block Find the most recent point history before this block
     */
    function _findUserBlockEpoch(address _addr, uint256 _block)
        internal
        view
        returns(uint256)
    {
        uint256 min = 0;
        uint256 max = userPointEpoch[_addr];
        for(uint256 i = 0; i < 128; i++) {
            if(min >= max){
                break;
            }
            uint256 mid = (min.add(max).add(1)).div(2);
            if(userPointHistory[_addr][mid].blk <= _block){
                min = mid;
            } else {
                max = mid.sub(1);
            }
        }
        return min;
    }

    /**
     * @dev Gets curent user voting weight (aka effectiveStake)
     * @param _owner User for which to return the balance
     * @return uint256 Balance of user
     */
    function balanceOf(address _owner)
        public
        view
        returns (uint256)
    {
        uint256 epoch = userPointEpoch[_owner];
        if(epoch == 0){
            return 0;
        }
        Point memory lastPoint = userPointHistory[_owner][epoch];
        lastPoint.bias = lastPoint.bias.sub(lastPoint.slope.mul(int128(block.timestamp.sub(lastPoint.ts))));
        if(lastPoint.bias < 0) {
            lastPoint.bias = 0;
        }
        return uint256(lastPoint.bias);
    }

    /**
     * @dev Gets a users votingWeight at a given blockNumber
     * @param _owner User for which to return the balance
     * @param _blockNumber Block at which to calculate balance
     * @return uint256 Balance of user
     */
    function balanceOfAt(address _owner, uint256 _blockNumber)
        public
        view
        returns (uint256)
    {
        require(_blockNumber <= block.number, "Must pass block number in the past");

        // Get most recent user Point to block
        uint256 userEpoch = _findUserBlockEpoch(_owner, _blockNumber);
        if(userEpoch == 0){
            return 0;
        }
        Point memory upoint = userPointHistory[_owner][userEpoch];

        // Get most recent global Point to block
        uint256 maxEpoch = globalEpoch;
        uint256 epoch = _findBlockEpoch(_blockNumber, maxEpoch);
        Point memory point0 = pointHistory[epoch];

        // Calculate delta (block & time) between user Point and target block
        // Allowing us to calculate the average seconds per block between
        // the two points
        uint256 dBlock = 0;
        uint256 dTime = 0;
        if(epoch < maxEpoch){
            Point memory point1 = pointHistory[epoch.add(1)];
            dBlock = point1.blk.sub(point0.blk);
            dTime = point1.ts.sub(point0.ts);
        } else {
            dBlock = block.number.sub(point0.blk);
            dTime = block.timestamp.sub(point0.ts);
        }
        // (Deterministically) Estimate the time at which block _blockNumber was mined
        uint256 blockTime = point0.ts;
        if(dBlock != 0) {
            // blockTime += dTime * (_blockNumber - point0.blk) / dBlock;
            blockTime = blockTime.add(dTime.mul(_blockNumber.sub(point0.blk)).div(dBlock));
        }
        // Current Bias = most recent bias - (slope * time since update)
        upoint.bias = upoint.bias.sub(upoint.slope.mul(int128(blockTime.sub(upoint.ts))));
        if(upoint.bias >= 0){
            return uint256(upoint.bias);
        } else {
            return 0;
        }
    }

    /**
     * @dev Calculates total supply of votingWeight at a given time _t
     * @param _point Most recent point before time _t
     * @param _t Time at which to calculate supply
     * @return totalSupply at given point in time
     */
    function _supplyAt(Point memory _point, uint256 _t)
        internal
        view
        returns (uint256)
    {
        Point memory lastPoint = _point;
        // Floor the timestamp to weekly interval
        uint256 iterativeTime = _floorToWeek(lastPoint.ts);
        // Iterate through all weeks between _point & _t to account for slope changes
        for(uint256 i = 0; i < 255; i++){
            iterativeTime = iterativeTime.add(WEEK);
            int128 dSlope = 0;
            // If week end is after timestamp, then truncate & leave dSlope to 0
            if(iterativeTime > _t){
                iterativeTime = _t;
            }
            // else get most recent slope change
            else {
                dSlope = slopeChanges[iterativeTime];
            }

            // lastPoint.bias -= lastPoint.slope * convert(iterativeTime - lastPoint.ts, int128)
            lastPoint.bias = lastPoint.bias.sub(lastPoint.slope.mul(int128(iterativeTime.sub(lastPoint.ts))));
            if(iterativeTime == _t){
                break;
            }
            lastPoint.slope = lastPoint.slope.add(dSlope);
            lastPoint.ts = iterativeTime;
        }

        if (lastPoint.bias < 0){
            lastPoint.bias = 0;
        }
        return uint256(lastPoint.bias);
    }

    /**
     * @dev Calculates current total supply of votingWeight
     * @return totalSupply of voting token weight
     */
    function totalSupply()
        public
        view
        returns (uint256)
    {
        uint256 epoch_ = globalEpoch;
        Point memory lastPoint = pointHistory[epoch_];
        return _supplyAt(lastPoint, block.timestamp);
    }

    /**
     * @dev Calculates total supply of votingWeight at a given blockNumber
     * @param _blockNumber Block number at which to calculate total supply
     * @return totalSupply of voting token weight at the given blockNumber
     */
    function totalSupplyAt(uint256 _blockNumber)
        public
        view
        returns (uint256)
    {
        require(_blockNumber <= block.number, "Must pass block number in the past");

        uint256 epoch = globalEpoch;
        uint256 targetEpoch = _findBlockEpoch(_blockNumber, epoch);

        Point memory point = pointHistory[targetEpoch];

        // If point.blk > _blockNumber that means we got the initial epoch & contract did not yet exist
        if(point.blk > _blockNumber){
            return 0;
        }

        uint256 dTime = 0;
        if(targetEpoch < epoch){
            Point memory pointNext = pointHistory[targetEpoch.add(1)];
            if(point.blk != pointNext.blk) {
                dTime = (_blockNumber.sub(point.blk)).mul(pointNext.ts.sub(point.ts)).div(pointNext.blk.sub(point.blk));
            }
        } else if (point.blk != block.number){
            dTime = (_blockNumber.sub(point.blk)).mul(block.timestamp.sub(point.ts)).div(block.number.sub(point.blk));
        }
        // Now dTime contains info on how far are we beyond point

        return _supplyAt(point, point.ts.add(dTime));
    }


    /***************************************
                    REWARDS
    ****************************************/

    /** @dev Updates the reward for a given address, before executing function */
    modifier updateReward(address _account) {
        // Setting of global vars
        uint256 newRewardPerToken = rewardPerToken();
        // If statement protects against loss in initialisation case
        if(newRewardPerToken > 0) {
            rewardPerTokenStored = newRewardPerToken;
            lastUpdateTime = lastTimeRewardApplicable();
            // Setting of personal vars based on new globals
            if (_account != address(0)) {
                rewards[_account] = earned(_account);
                userRewardPerTokenPaid[_account] = newRewardPerToken;
            }
        }
        _;
    }

    /**
     * @dev Claims outstanding rewards for the sender.
     * First updates outstanding reward allocation and then transfers.
     */
    function claimReward()
        public
        updateReward(msg.sender)
    {
        uint256 reward = rewards[msg.sender];
        if (reward > 0) {
            rewards[msg.sender] = 0;
            stakingToken.safeTransfer(msg.sender, reward);
            rewardsPaid[msg.sender] = rewardsPaid[msg.sender].add(reward);
            emit RewardPaid(msg.sender, reward);
        }
    }


    /***************************************
                REWARDS - GETTERS
    ****************************************/

    /**
     * @dev Gets the most recent Static Balance (bias) for a user
     * @param _addr User for which to retrieve static balance
     * @return uint256 balance
     */
    function staticBalanceOf(address _addr)
        public
        view
        returns (uint256)
    {
        uint256 uepoch = userPointEpoch[_addr];
        if(uepoch == 0 || userPointHistory[_addr][uepoch].bias == 0){
            return 0;
        }
        return _staticBalance(userPointHistory[_addr][uepoch].slope, userPointHistory[_addr][uepoch].ts, locked[_addr].end);
    }

    function _staticBalance(int128 _slope, uint256 _startTime, uint256 _endTime)
        internal
        pure
        returns (uint256)
    {
        if(_startTime > _endTime) return 0;
        // get lockup length (end - point.ts)
        uint256 lockupLength = _endTime.sub(_startTime);
        // s = amount * sqrt(length)
        uint256 s = uint256(_slope.mul(10000)).mul(Root.sqrt(lockupLength));
        return s;
    }

    /**
     * @dev Gets the RewardsToken
     */
    function getRewardToken()
        external
        view
        returns (IERC20)
    {
        return stakingToken;
    }

    /**
     * @dev Gets the duration of the rewards period
     */
    function getDuration()
        external
        pure
        returns (uint256)
    {
        return WEEK;
    }

    /**
     * @dev Gets the last applicable timestamp for this reward period
     */
    function lastTimeRewardApplicable()
        public
        view
        returns (uint256)
    {
        return StableMath.min(block.timestamp, periodFinish);
    }

    /**
     * @dev Calculates the amount of unclaimed rewards per token since last update,
     * and sums with stored to give the new cumulative reward per token
     * @return 'Reward' per staked token
     */
    function rewardPerToken()
        public
        view
        returns (uint256)
    {
        // If there is no StakingToken liquidity, avoid div(0)
        uint256 totalStatic = totalStaticWeight;
        if (totalStatic == 0) {
            return rewardPerTokenStored;
        }
        // new reward units to distribute = rewardRate * timeSinceLastUpdate
        uint256 rewardUnitsToDistribute = rewardRate.mul(lastTimeRewardApplicable().sub(lastUpdateTime));
        // new reward units per token = (rewardUnitsToDistribute * 1e18) / totalTokens
        uint256 unitsToDistributePerToken = rewardUnitsToDistribute.divPrecisely(totalStatic);
        // return summed rate
        return rewardPerTokenStored.add(unitsToDistributePerToken);
    }

    /**
     * @dev Calculates the amount of unclaimed rewards a user has earned
     * @param _addr User address
     * @return Total reward amount earned
     */
    function earned(address _addr)
        public
        view
        returns (uint256)
    {
        // current rate per token - rate user previously received
        uint256 userRewardDelta = rewardPerToken().sub(userRewardPerTokenPaid[_addr]);
        // new reward = staked tokens * difference in rate
        uint256 userNewReward = staticBalanceOf(_addr).mulTruncate(userRewardDelta);
        // add to previous rewards
        return rewards[_addr].add(userNewReward);
    }


    /***************************************
                REWARDS - ADMIN
    ****************************************/

    /**
     * @dev Notifies the contract that new rewards have been added.
     * Calculates an updated rewardRate based on the rewards in period.
     * @param _reward Units of RewardToken that have been added to the pool
     */
    function notifyRewardAmount(uint256 _reward)
        external
        onlyRewardsDistributor
        contractNotExpired
        updateReward(address(0))
    {
        uint256 currentTime = block.timestamp;
        // If previous period over, reset rewardRate
        if (currentTime >= periodFinish) {
            rewardRate = _reward.div(WEEK);
        }
        // If additional reward to existing period, calc sum
        else {
            uint256 remaining = periodFinish.sub(currentTime);
            uint256 leftover = remaining.mul(rewardRate);
            rewardRate = _reward.add(leftover).div(WEEK);
        }

        lastUpdateTime = currentTime;
        periodFinish = currentTime.add(WEEK);

        emit RewardAdded(_reward);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_stakingToken","type":"address"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"address","name":"_nexus","type":"address"},{"internalType":"address","name":"_rewardsDistributor","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"provider","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"locktime","type":"uint256"},{"indexed":true,"internalType":"enum IncentivisedVotingLockup.LockAction","name":"action","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"ts","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"ejected","type":"address"},{"indexed":false,"internalType":"address","name":"ejector","type":"address"},{"indexed":false,"internalType":"uint256","name":"ts","type":"uint256"}],"name":"Ejected","type":"event"},{"anonymous":false,"inputs":[],"name":"Expired","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"provider","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ts","type":"uint256"}],"name":"Withdraw","type":"event"},{"constant":true,"inputs":[],"name":"END","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MAXTIME","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"_blockNumber","type":"uint256"}],"name":"balanceOfAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"checkpoint","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"claimReward","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"},{"internalType":"uint256","name":"_unlockTime","type":"uint256"}],"name":"createLock","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_addr","type":"address"}],"name":"earned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_addr","type":"address"}],"name":"eject","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"exit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"expireContract","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"expired","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_addr","type":"address"}],"name":"getLastUserPoint","outputs":[{"internalType":"int128","name":"bias","type":"int128"},{"internalType":"int128","name":"slope","type":"int128"},{"internalType":"uint256","name":"ts","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getRewardToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"globalEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"increaseLockAmount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_unlockTime","type":"uint256"}],"name":"increaseLockLength","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"lastTimeRewardApplicable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastUpdateTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"locked","outputs":[{"internalType":"int128","name":"amount","type":"int128"},{"internalType":"uint256","name":"end","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"nexus","outputs":[{"internalType":"contract INexus","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_reward","type":"uint256"}],"name":"notifyRewardAmount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"periodFinish","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"pointHistory","outputs":[{"internalType":"int128","name":"bias","type":"int128"},{"internalType":"int128","name":"slope","type":"int128"},{"internalType":"uint256","name":"ts","type":"uint256"},{"internalType":"uint256","name":"blk","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"rewardPerToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"rewardPerTokenStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"rewardRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"rewardsDistributor","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewardsPaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_rewardsDistributor","type":"address"}],"name":"setRewardsDistribution","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"slopeChanges","outputs":[{"internalType":"int128","name":"","type":"int128"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"stakingToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_addr","type":"address"}],"name":"staticBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalStaticWeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_blockNumber","type":"uint256"}],"name":"totalSupplyAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userPointEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"userPointHistory","outputs":[{"internalType":"int128","name":"bias","type":"int128"},{"internalType":"int128","name":"slope","type":"int128"},{"internalType":"uint256","name":"ts","type":"uint256"},{"internalType":"uint256","name":"blk","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userRewardPerTokenPaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]

60806040526004805460ff191690556012600d8190556000600e819055600f8190556010819055601181905590553480156200003a57600080fd5b50604051620042cf380380620042cf833981810160405260a08110156200006057600080fd5b8151602083018051604051929492938301929190846401000000008211156200008857600080fd5b9083019060208201858111156200009e57600080fd5b8251640100000000811182820188101715620000b957600080fd5b82525081516020918201929091019080838360005b83811015620000e8578181015183820152602001620000ce565b50505050905090810190601f168015620001165780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200013a57600080fd5b9083019060208201858111156200015057600080fd5b82516401000000008111828201881017156200016b57600080fd5b82525081516020918201929091019080838360005b838110156200019a57818101518382015260200162000180565b50505050905090810190601f168015620001c85780820380516001836020036101000a031916815260200191505b50604090815260208201519101516000805460ff1916600117905590925090508181816001600160a01b03811662000247576040805162461bcd60e51b815260206004820152601560248201527f4e65787573206973207a65726f20616464726573730000000000000000000000604482015290519081900360640190fd5b600080546001600160a01b0392831661010002610100600160a81b0319909116179055600180549282166001600160a01b031993841617905560028054918916919092161790555062000299620004ef565b50604080516080810182526000808252602080830182815242848601908152436060860190815260068054600181018255955285517ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f6003909602958601805494516001600160801b0319909516600f92830b6001600160801b03908116919091178116600160801b9690930b169490940217909255517ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d40840155517ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d4190920191909155825163313ce56760e01b8152925191926001600160a01b0389169263313ce56792600480840193919291829003018186803b158015620003bc57600080fd5b505afa158015620003d1573d6000803e3d6000fd5b505050506040513d6020811015620003e857600080fd5b505160ff16600d81905560121015620004335760405162461bcd60e51b8152600401808060200182810382526021815260200180620042ae6021913960400191505060405180910390fd5b84516200044890600b9060208801906200051d565b5083516200045e90600c9060208701906200051d565b506200047d6301e13380426200048d60201b6200226f1790919060201c565b60035550620005c2945050505050565b600082820183811015620004e8576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b60405180608001604052806000600f0b81526020016000600f0b815260200160008152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200056057805160ff191683800117855562000590565b8280016001018555821562000590579182015b828111156200059057825182559160200191906001019062000573565b506200059e929150620005a2565b5090565b620005bf91905b808211156200059e5760008155600101620005a9565b90565b613cdc80620005d26000396000f3fe608060405234801561001057600080fd5b506004361061027e5760003560e01c806380faa57d1161015c578063b88a802f116100ce578063df136d6511610087578063df136d6514610705578063e9fad8ee1461070d578063ebe2b12b14610715578063ee00ef3a1461071d578063efe7a50414610725578063f52a36f71461072d5761027e565b8063b88a802f1461064e578063c2c4c5c114610656578063c4698ee51461065e578063c8f33c91146106ac578063cbf9fe5f146106b4578063cd3daf9d146106fd5761027e565b806395d89b411161012057806395d89b41146105ee578063981b24d0146105f6578063a3f5c1d214610613578063ad2e8c9b1461061b578063af5bb34e14610623578063b52c05fe1461062b5761027e565b806380faa57d1461055757806381fc83bb1461055f5780638ad4c447146105855780638b876347146105a2578063901d13e2146105c85761027e565b80633fdd420e116101f557806363160282116101b957806363160282146104d657806369940d79146104f3578063700a4a74146104fb57806370a082311461052157806372f702f3146105475780637b0a47ee1461054f5761027e565b80633fdd420e14610443578063403f4447146104695780634c2067c7146104865780634ee2cd7e146104a25780635719098b146104ce5761027e565b806319762143116102475780631976214314610370578063313ce5671461039657806334d901a41461039e5780633c6b16ab146103fa5780633ccfd60b146104175780633f2a55401461041f5761027e565b80628cc2621461028357806306fdde03146102bb5780630700037d146103385780630f73d0b41461035e57806318160ddd14610368575b600080fd5b6102a96004803603602081101561029957600080fd5b50356001600160a01b0316610763565b60408051918252519081900360200190f35b6102c36107e9565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102fd5781810151838201526020016102e5565b50505050905090810190601f16801561032a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102a96004803603602081101561034e57600080fd5b50356001600160a01b0316610877565b610366610889565b005b6102a9610a29565b6103666004803603602081101561038657600080fd5b50356001600160a01b0316610aab565b6102a9610b36565b6103ca600480360360408110156103b457600080fd5b506001600160a01b038135169060200135610b3c565b60408051600f95860b860b815293850b90940b602084015282840191909152606082015290519081900360800190f35b6103666004803603602081101561041057600080fd5b5035610b89565b610366610d6d565b610427610d78565b604080516001600160a01b039092168252519081900360200190f35b6102a96004803603602081101561045957600080fd5b50356001600160a01b0316610d87565b6103666004803603602081101561047f57600080fd5b5035610e98565b61048e6110e1565b604080519115158252519081900360200190f35b6102a9600480360360408110156104b857600080fd5b506001600160a01b0381351690602001356110ea565b6102a96113f3565b610366600480360360208110156104ec57600080fd5b50356113f9565b610427611697565b6102a96004803603602081101561051157600080fd5b50356001600160a01b03166116a6565b6102a96004803603602081101561053757600080fd5b50356001600160a01b03166116b8565b6104276117c5565b6102a96117d4565b6102a96117da565b6102a96004803603602081101561057557600080fd5b50356001600160a01b03166117ed565b6103ca6004803603602081101561059b57600080fd5b50356117ff565b6102a9600480360360208110156105b857600080fd5b50356001600160a01b0316611840565b610366600480360360208110156105de57600080fd5b50356001600160a01b0316611852565b6102c36119fb565b6102a96004803603602081101561060c57600080fd5b5035611a56565b610427611ca1565b6102a9611cb5565b6102a9611cbc565b6103666004803603604081101561064157600080fd5b5080359060200135611cc2565b610366611f58565b610366612069565b6106846004803603602081101561067457600080fd5b50356001600160a01b0316612080565b60408051600f94850b850b815292840b90930b60208301528183015290519081900360600190f35b6102a9612149565b6106da600480360360208110156106ca57600080fd5b50356001600160a01b031661214f565b6040518083600f0b600f0b81526020018281526020019250505060405180910390f35b6102a961216f565b6102a96121d8565b6103666121de565b6102a96121ef565b6102a96121f5565b6102a96121fd565b61074a6004803603602081101561074357600080fd5b5035612203565b60408051600f92830b90920b8252519081900360200190f35b6001600160a01b03811660009081526013602052604081205481906107969061078a61216f565b9063ffffffff61221816565b905060006107b3826107a786610d87565b9063ffffffff61225a16565b6001600160a01b0385166000908152601460205260409020549091506107df908263ffffffff61226f16565b925050505b919050565b600b805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561086f5780601f106108445761010080835404028352916020019161086f565b820191906000526020600020905b81548152906001019060200180831161085257829003601f168201915b505050505081565b60146020526000908152604090205481565b6108916122c9565b6001600160a01b0316336001600160a01b0316146108f2576040805162461bcd60e51b81526020600482015260196024820152784f6e6c7920676f7665726e6f722063616e206578656375746560381b604482015290519081900360640190fd5b60045460ff1615610940576040805162461bcd60e51b815260206004820152601360248201527210dbdb9d1c9858dd081a5cc8195e1c1a5c9959606a1b604482015290519081900360640190fd5b60008061094b61216f565b905080156109a35760128190556109606117da565b6011556001600160a01b038216156109a35761097b82610763565b6001600160a01b03831660009081526014602090815260408083209390935560139052208190555b600e5442116109ef576040805162461bcd60e51b81526020600482015260136024820152722832b934b7b21036bab9ba1031329037bb32b960691b604482015290519081900360640190fd5b6004805460ff191660011790556040517f203d82d8d99f63bfecc8335216735e0271df4249ea752b030f9ab305b94e5afe90600090a15050565b600554600090610a37613ad3565b60068281548110610a4457fe5b60009182526020918290206040805160808101825260039093029091018054600f81810b810b810b8552600160801b909104810b810b900b9383019390935260018301549082015260029091015460608201529050610aa38142612349565b925050505b90565b610ab36122c9565b6001600160a01b0316336001600160a01b031614610b14576040805162461bcd60e51b81526020600482015260196024820152784f6e6c7920676f7665726e6f722063616e206578656375746560381b604482015290519081900360640190fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b600d5481565b60076020528160005260406000208181548110610b5557fe5b6000918252602090912060039091020180546001820154600290920154600f82810b9550600160801b90920490910b925084565b6001546001600160a01b03163314610be8576040805162461bcd60e51b815260206004820181905260248201527f43616c6c6572206973206e6f7420726577617264206469737472696275746f72604482015290519081900360640190fd5b60045460ff1615610c36576040805162461bcd60e51b815260206004820152601360248201527210dbdb9d1c9858dd081a5cc8195e1c1a5c9959606a1b604482015290519081900360640190fd5b600080610c4161216f565b90508015610c99576012819055610c566117da565b6011556001600160a01b03821615610c9957610c7182610763565b6001600160a01b03831660009081526014602090815260408083209390935560139052208190555b600e5442908110610cbf57610cb78462093a8063ffffffff61245d16565b600f55610d19565b600e54600090610cd5908363ffffffff61221816565b90506000610cee600f548361249f90919063ffffffff16565b9050610d1362093a80610d07888463ffffffff61226f16565b9063ffffffff61245d16565b600f5550505b6011819055610d318162093a8063ffffffff61226f16565b600e556040805185815290517fde88a922e0d3b88b24e9623efeb464919c6bf9f66857a65e2bfcf2ce87a9433d9181900360200190a150505050565b610d76336124f8565b565b6001546001600160a01b031681565b6001600160a01b038116600090815260086020526040812054801580610de657506001600160a01b0383166000908152600760205260409020805482908110610dcc57fe5b6000918252602090912060039091020154600f90810b900b155b15610df55760009150506107e4565b6001600160a01b03831660009081526007602052604090208054610e91919083908110610e1e57fe5b600091825260208083206003909202909101546001600160a01b0387168352600790915260409091208054600160801b909204600f0b9184908110610e5f57fe5b6000918252602080832060016003909302018201546001600160a01b0389168452600a90915260409092200154612794565b9392505050565b60005460ff16610edd576040805162461bcd60e51b815260206004820152601f6024820152600080516020613b19833981519152604482015290519081900360640190fd5b6000805460ff1916905560045460ff1615610f35576040805162461bcd60e51b815260206004820152601360248201527210dbdb9d1c9858dd081a5cc8195e1c1a5c9959606a1b604482015290519081900360640190fd5b336000610f4061216f565b90508015610f98576012819055610f556117da565b6011556001600160a01b03821615610f9857610f7082610763565b6001600160a01b03831660009081526014602090815260408083209390935560139052208190555b610fa0613b01565b50604080518082018252336000818152600a60208181529482208054600f90810b900b8552929091528352600101549181019190915283611028576040805162461bcd60e51b815260206004820152601a60248201527f4d757374207374616b65206e6f6e207a65726f20616d6f756e74000000000000604482015290519081900360640190fd5b60008160000151600f0b1361107d576040805162461bcd60e51b8152602060048201526016602482015275139bc8195e1a5cdd1a5b99c81b1bd8dac8199bdd5b9960521b604482015290519081900360640190fd5b428160200151116110bf5760405162461bcd60e51b8152600401808060200182810382526024815260200180613b396024913960400191505060405180910390fd5b6110ce338560008460016127ed565b50506000805460ff191660011790555050565b60045460ff1681565b60004382111561112b5760405162461bcd60e51b8152600401808060200182810382526022815260200180613b7e6022913960400191505060405180910390fd5b60006111378484612916565b9050806111485760009150506113ed565b611150613ad3565b6001600160a01b038516600090815260076020526040902080548390811061117457fe5b600091825260208083206040805160808101825260039094029091018054600f81810b810b810b8652600160801b909104810b810b900b92840192909252600182015490830152600201546060820152600554909250906111d586836129df565b90506111df613ad3565b600682815481106111ec57fe5b600091825260208083206040805160808101825260039094029091018054600f81810b810b810b8652600160801b909104810b810b900b92840192909252600182015490830152600201546060820152915080848410156112fc5761124f613ad3565b600661126286600163ffffffff61226f16565b8154811061126c57fe5b60009182526020918290206040805160808101825260039093029091018054600f81810b810b810b8552600160801b909104810b810b900b9383019390935260018301549082015260029091015460608083018290528601519192506112d79163ffffffff61221816565b92506112f48460400151826040015161221890919063ffffffff16565b91505061132e565b606083015161131290439063ffffffff61221816565b915061132b83604001514261221890919063ffffffff16565b90505b604083015182156113775761137461136784610d0761135a88606001518f61221890919063ffffffff16565b869063ffffffff61249f16565b829063ffffffff61226f16565b90505b6113b96113a861139489604001518461221890919063ffffffff16565b60208a0151600f0b9063ffffffff612a6216565b8851600f0b9063ffffffff612b2d16565b600f90810b810b8089526000910b126113e05750509351600f0b95506113ed945050505050565b6000985050505050505050505b92915050565b60055481565b60005460ff1661143e576040805162461bcd60e51b815260206004820152601f6024820152600080516020613b19833981519152604482015290519081900360640190fd5b6000805460ff1916905560045460ff1615611496576040805162461bcd60e51b815260206004820152601360248201527210dbdb9d1c9858dd081a5cc8195e1c1a5c9959606a1b604482015290519081900360640190fd5b3360006114a161216f565b905080156114f95760128190556114b66117da565b6011556001600160a01b038216156114f9576114d182610763565b6001600160a01b03831660009081526014602090815260408083209390935560139052208190555b611501613b01565b50604080518082018252336000818152600a60208181529482208054600f90810b900b85529282528452600190910154928201929092529061154285612ba5565b905060008260000151600f0b13611594576040805162461bcd60e51b8152602060048201526011602482015270139bdd1a1a5b99c81a5cc81b1bd8dad959607a1b604482015290519081900360640190fd5b428260200151116115db576040805162461bcd60e51b815260206004820152600c60248201526b131bd8dac8195e1c1a5c995960a21b604482015290519081900360640190fd5b81602001518111611633576040805162461bcd60e51b815260206004820152601b60248201527f43616e206f6e6c7920696e637265617365206c6f636b205745454b0000000000604482015290519081900360640190fd5b6003548111156116745760405162461bcd60e51b815260040180806020018281038252602b815260200180613c2f602b913960400191505060405180910390fd5b611683336000838560026127ed565b50506000805460ff19166001179055505050565b6002546001600160a01b031690565b60156020526000908152604090205481565b6001600160a01b038116600090815260086020526040812054806116e05760009150506107e4565b6116e8613ad3565b6001600160a01b038416600090815260076020526040902080548390811061170c57fe5b60009182526020918290206040805160808101825260039093029091018054600f81810b810b810b8552600160801b909104810b810b900b938301939093526001830154908201819052600290920154606082015291506117a1906117909061177c90429063ffffffff61221816565b6020840151600f0b9063ffffffff612a6216565b8251600f0b9063ffffffff612b2d16565b600f90810b810b8083526000910b12156117ba57600081525b51600f0b9392505050565b6002546001600160a01b031681565b600f5481565b60006117e842600e54612bbe565b905090565b60086020526000908152604090205481565b6006818154811061180c57fe5b6000918252602090912060039091020180546001820154600290920154600f82810b9450600160801b90920490910b919084565b60136020526000908152604090205481565b60045460ff16156118a0576040805162461bcd60e51b815260206004820152601360248201527210dbdb9d1c9858dd081a5cc8195e1c1a5c9959606a1b604482015290519081900360640190fd5b806118a9613b01565b506001600160a01b0381166000908152600a6020908152604080832081518083019092528054600f90810b810b810b808452600190920154938301939093529092910b1380156118fd575080602001514210155b61194e576040805162461bcd60e51b815260206004820152601860248201527f5573657273206c6f636b206469646e2774206578706972650000000000000000604482015290519081900360640190fd5b600061195983610d87565b116119ab576040805162461bcd60e51b815260206004820152601c60248201527f55736572206d7573742068617665206578697374696e67206269617300000000604482015290519081900360640190fd5b6119b4836124f8565b6040805132815242602082015281516001600160a01b038616927f3a1df3c76d2dfab31786674a912f29b53c3a12a052fe94502a99e66f9286bf3f928290030190a2505050565b600c805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561086f5780601f106108445761010080835404028352916020019161086f565b600043821115611a975760405162461bcd60e51b8152600401808060200182810382526022815260200180613b7e6022913960400191505060405180910390fd5b6005546000611aa684836129df565b9050611ab0613ad3565b60068281548110611abd57fe5b60009182526020918290206040805160808101825260039093029091018054600f81810b810b810b8552600160801b909104810b810b900b9383019390935260018301549082015260029091015460608201819052909150851015611b2857600093505050506107e4565b600083831015611c1f57611b3a613ad3565b6006611b4d85600163ffffffff61226f16565b81548110611b5757fe5b60009182526020918290206040805160808101825260039093029091018054600f81810b810b810b8552600160801b909104810b810b900b93830193909352600183015490820152600290910154606080830182905285015191925014611c1957611c16611bd68460600151836060015161221890919063ffffffff16565b610d07611bf48660400151856040015161221890919063ffffffff16565b6060870151611c0a908c9063ffffffff61221816565b9063ffffffff61249f16565b91505b50611c77565b43826060015114611c7757611c74611c4483606001514361221890919063ffffffff16565b610d07611c5e85604001514261221890919063ffffffff16565b6060860151611c0a908b9063ffffffff61221816565b90505b611c9782611c9283856040015161226f90919063ffffffff16565b612349565b9695505050505050565b60005461010090046001600160a01b031681565b62093a8090565b60105481565b60005460ff16611d07576040805162461bcd60e51b815260206004820152601f6024820152600080516020613b19833981519152604482015290519081900360640190fd5b6000805460ff1916905560045460ff1615611d5f576040805162461bcd60e51b815260206004820152601360248201527210dbdb9d1c9858dd081a5cc8195e1c1a5c9959606a1b604482015290519081900360640190fd5b336000611d6a61216f565b90508015611dc2576012819055611d7f6117da565b6011556001600160a01b03821615611dc257611d9a82610763565b6001600160a01b03831660009081526014602090815260408083209390935560139052208190555b6000611dcd84612ba5565b9050611dd7613b01565b50604080518082018252336000818152600a60208181529482208054600f90810b900b8552929091528352600101549181019190915285611e5f576040805162461bcd60e51b815260206004820152601a60248201527f4d757374207374616b65206e6f6e207a65726f20616d6f756e74000000000000604482015290519081900360640190fd5b8051600f0b15611eb6576040805162461bcd60e51b815260206004820152601960248201527f5769746864726177206f6c6420746f6b656e7320666972737400000000000000604482015290519081900360640190fd5b428211611ef45760405162461bcd60e51b8152600401808060200182810382526026815260200180613c096026913960400191505060405180910390fd5b600354821115611f355760405162461bcd60e51b815260040180806020018281038252602b815260200180613c2f602b913960400191505060405180910390fd5b611f433387848460006127ed565b50506000805460ff1916600117905550505050565b336000611f6361216f565b90508015611fbb576012819055611f786117da565b6011556001600160a01b03821615611fbb57611f9382610763565b6001600160a01b03831660009081526014602090815260408083209390935560139052208190555b3360009081526014602052604090205480156120645733600081815260146020526040812055600254611ffa916001600160a01b039091169083612bd3565b3360009081526015602052604090205461201a908263ffffffff61226f16565b33600081815260156020908152604091829020939093558051848152905191927fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e048692918290030190a25b505050565b612071613b01565b61207d60008283612c25565b50565b6001600160a01b03811660009081526008602052604081205481908190806120b2575060009250829150819050612142565b6120ba613ad3565b6001600160a01b03861660009081526007602052604090208054839081106120de57fe5b60009182526020918290206040805160808101825260039093029091018054600f81810b810b810b808652600160801b909204810b810b900b9484018590526001820154928401839052600290910154606090930192909252909650909450925050505b9193909250565b60115481565b600a6020526000908152604090208054600190910154600f9190910b9082565b60105460009080612184575050601254610aa8565b60006121a661219760115461078a6117da565b600f549063ffffffff61249f16565b905060006121ba828463ffffffff61357716565b6012549091506121d0908263ffffffff61226f16565b935050505090565b60125481565b6121e7336124f8565b610d76611f58565b600e5481565b6301e1338081565b60035481565b600960205260009081526040902054600f0b81565b6000610e9183836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506135ac565b6000610e918383670de0b6b3a7640000613643565b600082820183811015610e91576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60008060019054906101000a90046001600160a01b03166001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b15801561231857600080fd5b505afa15801561232c573d6000803e3d6000fd5b505050506040513d602081101561234257600080fd5b5051905090565b6000612353613ad3565b83905060006123658260400151612ba5565b905060005b60ff81101561243b576123868262093a8063ffffffff61226f16565b915060008583111561239a578592506123ae565b50600082815260096020526040902054600f0b5b6123f06123df6123cb86604001518661221890919063ffffffff16565b6020870151600f0b9063ffffffff612a6216565b8551600f0b9063ffffffff612b2d16565b600f90810b900b845282861415612407575061243b565b602084015161241f90600f0b8263ffffffff61367116565b600f90810b900b6020850152506040830182905260010161236a565b5060008260000151600f0b121561245157600082525b5051600f0b9392505050565b6000610e9183836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506136e9565b6000826124ae575060006113ed565b828202828482816124bb57fe5b0414610e915760405162461bcd60e51b8152600401808060200182810382526021815260200180613bc16021913960400191505060405180910390fd5b60005460ff1661253d576040805162461bcd60e51b815260206004820152601f6024820152600080516020613b19833981519152604482015290519081900360640190fd5b6000805460ff19168155819061255161216f565b905080156125a95760128190556125666117da565b6011556001600160a01b038216156125a95761258182610763565b6001600160a01b03831660009081526014602090815260408083209390935560139052208190555b6125b1613b01565b506040805180820182526001600160a01b0385166000818152600a60208181529482208054600f90810b900b8552929091528352600101549181018290529042101580612600575060045460ff165b61264a576040805162461bcd60e51b8152602060048201526016602482015275546865206c6f636b206469646e27742065787069726560501b604482015290519081900360640190fd5b60008160000151600f0b136126a6576040805162461bcd60e51b815260206004820152601f60248201527f4d757374206861766520736f6d657468696e6720746f20776974686472617700604482015290519081900360640190fd5b8051600f0b6126b3613b01565b50604080518082018252600080825260208083018281526001600160a01b038a168352600a90915292902081518154600f9190910b6001600160801b03166001600160801b0319909116178155915160019092019190915560045460ff1661272057612720868483612c25565b60025461273d906001600160a01b0316878463ffffffff612bd316565b6040805183815242602082015281516001600160a01b038916927ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568928290030190a250506000805460ff1916600117905550505050565b6000818311156127a657506000610e91565b60006127b8838563ffffffff61221816565b90506000611c976127c88361374e565b6127de600f89900b61271063ffffffff612a6216565b600f0b9063ffffffff61249f16565b6127f5613b01565b50604080518082019091528251600f90810b80835260208086015190840152612825910b8663ffffffff61367116565b600f90810b900b8152831561283c57602081018490525b6001600160a01b0386166000908152600a6020908152604090912082518154600f9190910b6001600160801b03166001600160801b03199091161781559082015160019091015561288e868483612c25565b84156128b2576002546128b2906001600160a01b031687308863ffffffff61379816565b8160028111156128be57fe5b60208083015160408051898152928301919091524282820152516001600160a01b038916917fbe9cf0e939c614fad640a623a53ba0a807c8cb503c4c4c8dacabe27b86ff2dd5919081900360600190a3505050505050565b6001600160a01b0382166000908152600860205260408120548190815b60808110156129d557818310612948576129d5565b60006129706002610d076001612964888863ffffffff61226f16565b9063ffffffff61226f16565b6001600160a01b0388166000908152600760205260409020805491925087918390811061299957fe5b906000526020600020906003020160020154116129b8578093506129cc565b6129c981600163ffffffff61221816565b92505b50600101612933565b5090949350505050565b60008082815b60808110156129d5578183106129fa576129d5565b6000612a166002610d076001612964888863ffffffff61226f16565b90508660068281548110612a2657fe5b90600052602060002090600302016002015411612a4557809350612a59565b612a5681600163ffffffff61221816565b92505b506001016129e5565b600082600f0b60001415612a78575060006113ed565b82600f0b600019148015612a975750600f82900b60016001607f1b0319145b15612ad35760405162461bcd60e51b8152600401808060200182810382526027815260200180613be26027913960400191505060405180910390fd5b6000828402905082600f0b84600f0b82600f0b81612aed57fe5b05600f0b14610e915760405162461bcd60e51b8152600401808060200182810382526027815260200180613be26027913960400191505060405180910390fd5b6000818303600f83900b8213801590612b4c575083600f0b81600f0b13155b80612b6a5750600083600f0b128015612b6a575083600f0b81600f0b135b610e915760405162461bcd60e51b8152600401808060200182810382526024815260200180613c5a6024913960400191505060405180910390fd5b60006113ed62093a80611c0a848263ffffffff61245d16565b6000818311612bcd5782610e91565b50919050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526120649084906137f8565b612c2d613ad3565b612c35613ad3565b60055460009081906001600160a01b03881615612fb757428760200151118015612c66575060008760000151600f0b135b15612cb5578651612c8490600f0b6301e1338063ffffffff6139b016565b600f90810b900b602080870191909152870151612cab906123cb904263ffffffff61221816565b600f90810b900b85525b428660200151118015612ccf575060008660000151600f0b135b15612d32578551612ced90600f0b6301e1338063ffffffff6139b016565b600f90810b900b602080860191909152860151612d2890612d14904263ffffffff61221816565b6020860151600f0b9063ffffffff612a6216565b600f90810b900b84525b6001600160a01b03881660009081526008602052604090205480612dd4576001600160a01b0389166000908152600760209081526040808320805460018181018355918552938390208a516003909502018054938b0151600f90810b6001600160801b03908116600160801b029690910b81166001600160801b0319909516949094179093169390931782558801519181019190915560608701516002909101555b6000612de98660200151428a60200151612794565b90506000612e028260105461226f90919063ffffffff16565b90508215612eb4576001600160a01b038b1660009081526007602052604081208054612e9e919086908110612e3357fe5b906000526020600020906003020160000160109054906101000a9004600f0b600760008f6001600160a01b03166001600160a01b031681526020019081526020016000208681548110612e8257fe5b9060005260206000209060030201600101548d60200151612794565b9050612eb0828263ffffffff61221816565b9150505b6010819055612eca83600163ffffffff61226f16565b6001600160a01b038c16600081815260086020908152604080832094909455428b85019081524360608d01908152938352600782528483208054600181810183559185528385208e5160039092020180548f860151600f90810b6001600160801b03908116600160801b0294820b81166001600160801b03199093169290921790911692909217815592519183019190915593516002909101558d81015182526009815292902054918b015191900b965015612fb357896020015189602001511415612f9857859450612fb3565b6020808a0151600090815260099091526040902054600f0b94505b5050505b612fbf613ad3565b5060408051608081018252600080825260208201524291810191909152436060820152811561304b5760068281548110612ff557fe5b60009182526020918290206040805160808101825260039093029091018054600f81810b810b810b8552600160801b909104810b810b900b93830193909352600183015490820152600290910154606082015290505b6040810151613058613ad3565b50604080516080810182526000808252602082018190528483018051938301939093526060808601519083015291519091904211156130cd576130ca6130ab85604001514261221890919063ffffffff16565b610d076130c587606001514361221890919063ffffffff16565b613a80565b90505b60006130d884612ba5565b905060005b60ff8110156132e9576130f98262093a8063ffffffff61226f16565b915060004283111561310d57429250613121565b50600082815260096020526040902054600f0b5b6000613136611394858963ffffffff61221816565b885190915061314e90600f0b8263ffffffff612b2d16565b600f90810b810b8952602089015161316d910b8363ffffffff61367116565b600f90810b810b60208a015288516000910b121561318a57600088525b60008860200151600f0b12156131a257600060208901525b839650838860400181815250506131ea6131d96131cc88604001518761221890919063ffffffff16565b879063ffffffff61225a16565b60608801519063ffffffff61226f16565b606089015261320089600163ffffffff61226f16565b9850428414156132175750504360608701526132e9565b60068054600181018255600091909152885160039091027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f8101805460208c0151600f90810b6001600160801b03908116600160801b029590910b81166001600160801b031990921691909117169290921790915560408901517ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d4082015560608901517ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d419091015550506001016130dd565b5060058690556001600160a01b038d16156133a05761333361331f8b602001518b60200151600f0b612b2d90919063ffffffff16565b6020870151600f0b9063ffffffff61367116565b600f90810b810b60208701528a518a5161336b9261335a9291900b9063ffffffff612b2d16565b8651600f0b9063ffffffff61367116565b600f90810b810b865260208601516000910b121561338b57600060208601525b60008560000151600f0b12156133a057600085525b60068054600181018255600091909152855160039091027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f810180546020890151600f90810b6001600160801b03908116600160801b029590910b81166001600160801b031990921691909117169290921790915560408601517ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d4082015560608601517ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d41909101556001600160a01b038d161561356857428c6020015111156134fe5761349d8a6020015189600f0b61367190919063ffffffff16565b97508b602001518b6020015114156134cc576134c9896020015189600f0b612b2d90919063ffffffff16565b97505b60208c810151600090815260099091526040902080546001600160801b0319166001600160801b03600f8b900b161790555b428b602001511115613568578b602001518b60200151111561356857613534896020015188600f0b612b2d90919063ffffffff16565b60208c810151600090815260099091526040902080546001600160801b0319166001600160801b03600f84900b1617905596505b50505050505050505050505050565b60008061359284670de0b6b3a764000063ffffffff61249f16565b90506135a4818463ffffffff61245d16565b949350505050565b6000818484111561363b5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156136005781810151838201526020016135e8565b50505050905090810190601f16801561362d5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600080613656858563ffffffff61249f16565b9050613668818463ffffffff61245d16565b95945050505050565b6000828201600f83900b8213801590613690575083600f0b81600f0b12155b806136ae5750600083600f0b1280156136ae575083600f0b81600f0b125b610e915760405162461bcd60e51b8152600401808060200182810382526021815260200180613b5d6021913960400191505060405180910390fd5b600081836137385760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156136005781810151838201526020016135e8565b50600083858161374457fe5b0495945050505050565b6000806137676002610d0785600163ffffffff61226f16565b90508291505b81811015612bcd579050806137916002610d0783612964878263ffffffff61245d16565b905061376d565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b1790526137f29085906137f8565b50505050565b61380a826001600160a01b0316613a9a565b61385b576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b602083106138995780518252601f19909201916020918201910161387a565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146138fb576040519150601f19603f3d011682016040523d82523d6000602084013e613900565b606091505b509150915081613957576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b8051156137f25780806020019051602081101561397357600080fd5b50516137f25760405162461bcd60e51b815260040180806020018281038252602a815260200180613c7e602a913960400191505060405180910390fd5b600081600f0b60001415613a0b576040805162461bcd60e51b815260206004820181905260248201527f5369676e6564536166654d6174683a206469766973696f6e206279207a65726f604482015290519081900360640190fd5b81600f0b600019148015613a2a5750600f83900b60016001607f1b0319145b15613a665760405162461bcd60e51b8152600401808060200182810382526021815260200180613ba06021913960400191505060405180910390fd5b600082600f0b84600f0b81613a7757fe5b05949350505050565b60006113ed82670de0b6b3a764000063ffffffff61249f16565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708181148015906107df575050151592915050565b60405180608001604052806000600f0b81526020016000600f0b815260200160008152602001600081525090565b60408051808201909152600080825260208201529056fe5265656e7472616e637947756172643a207265656e7472616e742063616c6c0043616e6e6f742061646420746f2065787069726564206c6f636b2e2057697468647261775369676e6564536166654d6174683a206164646974696f6e206f766572666c6f774d757374207061737320626c6f636b206e756d62657220696e2074686520706173745369676e6564536166654d6174683a206469766973696f6e206f766572666c6f77536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775369676e6564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7743616e206f6e6c79206c6f636b20756e74696c2074696d6520696e2074686520667574757265566f74696e67206c6f636b2063616e20626520312079656172206d61782028756e74696c207265636f6c295369676e6564536166654d6174683a207375627472616374696f6e206f766572666c6f775361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a265627a7a7231582085e3f238d32bc335c149534b55f8b5ad9f7f0a75e0f25845c4d0885cf356b13a64736f6c6343000510003243616e6e6f742068617665206d6f7265207468616e20313820646563696d616c73000000000000000000000000a3bed4e1c75d00fa6f4e5e6922db7261b5e9acd200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000afce80b19a8ce13dec0739a1aab7a028d6845eb300000000000000000000000004dfdfa471b79cc9e6e8c355e6c71f8ec4916c50000000000000000000000000000000000000000000000000000000000000000a566f74696e67204d5441000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004764d544100000000000000000000000000000000000000000000000000000000

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

000000000000000000000000a3bed4e1c75d00fa6f4e5e6922db7261b5e9acd200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000afce80b19a8ce13dec0739a1aab7a028d6845eb300000000000000000000000004dfdfa471b79cc9e6e8c355e6c71f8ec4916c50000000000000000000000000000000000000000000000000000000000000000a566f74696e67204d5441000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004764d544100000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _stakingToken (address): 0xa3bed4e1c75d00fa6f4e5e6922db7261b5e9acd2
Arg [1] : _name (string): Voting MTA
Arg [2] : _symbol (string): vMTA
Arg [3] : _nexus (address): 0xafce80b19a8ce13dec0739a1aab7a028d6845eb3
Arg [4] : _rewardsDistributor (address): 0x04dfdfa471b79cc9e6e8c355e6c71f8ec4916c50

-----Encoded View---------------
9 Constructor Arguments found :
Arg [0] : 000000000000000000000000a3bed4e1c75d00fa6f4e5e6922db7261b5e9acd2
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [2] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [3] : 000000000000000000000000afce80b19a8ce13dec0739a1aab7a028d6845eb3
Arg [4] : 00000000000000000000000004dfdfa471b79cc9e6e8c355e6c71f8ec4916c50
Arg [5] : 000000000000000000000000000000000000000000000000000000000000000a
Arg [6] : 566f74696e67204d544100000000000000000000000000000000000000000000
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [8] : 764d544100000000000000000000000000000000000000000000000000000000


Deployed ByteCode Sourcemap

35914:32891:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;35914:32891:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67169:489;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;67169:489:0;-1:-1:-1;;;;;67169:489:0;;:::i;:::-;;;;;;;;;;;;;;;;37184:18;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;37184:18:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37714:42;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;37714:42:0;-1:-1:-1;;;;;37714:42:0;;:::i;54310:268::-;;;:::i;:::-;;61138:243;;;:::i;12044:165::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;12044:165:0;-1:-1:-1;;;;;12044:165:0;;:::i;37236:28::-;;;:::i;36909:51::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;36909:51:0;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68033:769;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;68033:769:0;;:::i;52336:83::-;;;:::i;11362:33::-;;;:::i;:::-;;;;-1:-1:-1;;;;;11362:33:0;;;;;;;;;;;;;;64519:390;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;64519:390:0;-1:-1:-1;;;;;64519:390:0;;:::i;50761:584::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;50761:584:0;;:::i;36787:27::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;57546:1869;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;57546:1869:0;;;;;;;;:::i;36842:26::-;;;:::i;51479:760::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;51479:760:0;;:::i;65412:127::-;;;:::i;37763:46::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;37763:46:0;-1:-1:-1;;;;;37763:46:0;;:::i;56786:509::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;56786:509:0;-1:-1:-1;;;;;56786:509:0;;:::i;36635:26::-;;;:::i;37366:29::-;;;:::i;65832:169::-;;;:::i;36967:49::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;36967:49:0;-1:-1:-1;;;;;36967:49:0;;:::i;36875:27::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;36875:27:0;;:::i;37650:57::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;37650:57:0;-1:-1:-1;;;;;37650:57:0;;:::i;53905:264::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;53905:264:0;-1:-1:-1;;;;;53905:264:0;;:::i;37209:20::-;;;:::i;61635:1171::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;61635:1171:0;;:::i;4606:19::-;;;:::i;65618:117::-;;;:::i;37457:36::-;;;:::i;49799:787::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;49799:787:0;;;;;;;:::i;63804:395::-;;;:::i;49492:124::-;;;:::i;39828:425::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;39828:425:0;-1:-1:-1;;;;;39828:425:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37500:33;;;:::i;37076:47::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;37076:47:0;-1:-1:-1;;;;;37076:47:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66227:765;;;:::i;37540:39::-;;;:::i;53576:103::-;;;:::i;37328:31::-;;;:::i;36713:42::-;;;:::i;36762:18::-;;;:::i;37023:46::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;37023:46:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;67169:489;-1:-1:-1;;;;;67387:29:0;;67248:7;67387:29;;;:22;:29;;;;;;67248:7;;67366:51;;:16;:14;:16::i;:::-;:20;:51;:20;:51;:::i;:::-;67340:77;;67488:21;67512:51;67547:15;67512:22;67528:5;67512:15;:22::i;:::-;:34;:51;:34;:51;:::i;:::-;-1:-1:-1;;;;;67617:14:0;;;;;;:7;:14;;;;;;67488:75;;-1:-1:-1;67617:33:0;;67488:75;67617:33;:18;:33;:::i;:::-;67610:40;;;;67169:489;;;;:::o;37184:18::-;;;;;;;;;;;;;;;-1:-1:-1;;37184:18:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;37714:42::-;;;;;;;;;;;;;:::o;54310:268::-;5081:11;:9;:11::i;:::-;-1:-1:-1;;;;;5067:25:0;:10;-1:-1:-1;;;;;5067:25:0;;5059:63;;;;;-1:-1:-1;;;5059:63:0;;;;;;;;;;;;-1:-1:-1;;;5059:63:0;;;;;;;;;;;;;;;38971:7;;;;38970:8;38962:40;;;;;-1:-1:-1;;;38962:40:0;;;;;;;;;;;;-1:-1:-1;;;38962:40:0;;;;;;;;;;;;;;;54434:1;63109:25;63137:16;:14;:16::i;:::-;63109:44;-1:-1:-1;63237:21:0;;63234:397;;63275:20;:40;;;63347:26;:24;:26::i;:::-;63330:14;:43;-1:-1:-1;;;;;63454:22:0;;;63450:170;;63517:16;63524:8;63517:6;:16::i;:::-;-1:-1:-1;;;;;63497:17:0;;;;;;:7;:17;;;;;;;;:36;;;;63552:22;:32;;;:52;;;63450:170;54480:12;;54462:15;:30;54454:62;;;;;-1:-1:-1;;;54454:62:0;;;;;;;;;;;;-1:-1:-1;;;54454:62:0;;;;;;;;;;;;;;;54529:7;:14;;-1:-1:-1;;54529:14:0;54539:4;54529:14;;;54561:9;;;;54529:7;;54561:9;39013:1;;54310:268::o;61138:243::-;61251:11;;61209:7;;61273:22;;:::i;:::-;61298:12;61311:6;61298:20;;;;;;;;;;;;;;;;;61273:45;;;;;;;;61298:20;;;;;;;61273:45;;;;;;;;;;;;-1:-1:-1;;;61273:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;61336:37:0;61273:45;61357:15;61336:9;:37::i;:::-;61329:44;;;;61138:243;;:::o;12044:165::-;5081:11;:9;:11::i;:::-;-1:-1:-1;;;;;5067:25:0;:10;-1:-1:-1;;;;;5067:25:0;;5059:63;;;;;-1:-1:-1;;;5059:63:0;;;;;;;;;;;;-1:-1:-1;;;5059:63:0;;;;;;;;;;;;;;;12161:18;:40;;-1:-1:-1;;;;;;12161:40:0;-1:-1:-1;;;;;12161:40:0;;;;;;;;;;12044:165::o;37236:28::-;;;;:::o;36909:51::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;36909:51:0;;;;;;;-1:-1:-1;36909:51:0;:::o;68033:769::-;11798:18;;-1:-1:-1;;;;;11798:18:0;11784:10;:32;11776:77;;;;;-1:-1:-1;;;11776:77:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38971:7;;;;38970:8;38962:40;;;;;-1:-1:-1;;;38962:40:0;;;;;;;;;;;;-1:-1:-1;;;38962:40:0;;;;;;;;;;;;;;;68186:1;63109:25;63137:16;:14;:16::i;:::-;63109:44;-1:-1:-1;63237:21:0;;63234:397;;63275:20;:40;;;63347:26;:24;:26::i;:::-;63330:14;:43;-1:-1:-1;;;;;63454:22:0;;;63450:170;;63517:16;63524:8;63517:6;:16::i;:::-;-1:-1:-1;;;;;63497:17:0;;;;;;:7;:17;;;;;;;;:36;;;;63552:22;:32;;;:52;;;63450:170;68327:12;;68228:15;;68312:27;;68308:361;;68369:17;:7;36700:6;68369:17;:11;:17;:::i;:::-;68356:10;:30;68308:361;;;68510:12;;68490:17;;68510:29;;68527:11;68510:29;:16;:29;:::i;:::-;68490:49;;68554:16;68573:25;68587:10;;68573:9;:13;;:25;;;;:::i;:::-;68554:44;-1:-1:-1;68626:31:0;36700:6;68626:21;:7;68554:44;68626:21;:11;:21;:::i;:::-;:25;:31;:25;:31;:::i;:::-;68613:10;:44;-1:-1:-1;;68308:361:0;68681:14;:28;;;68735:21;68698:11;36700:6;68735:21;:15;:21;:::i;:::-;68720:12;:36;68774:20;;;;;;;;;;;;;;;;;63641:1;39013;;68033:769;:::o;52336:83::-;52390:21;52400:10;52390:9;:21::i;:::-;52336:83::o;11362:33::-;;;-1:-1:-1;;;;;11362:33:0;;:::o;64519:390::-;-1:-1:-1;;;;;64649:21:0;;64607:7;64649:21;;;:14;:21;;;;;;64684:11;;;:56;;-1:-1:-1;;;;;;64699:23:0;;;;;;:16;:23;;;;;:31;;64723:6;;64699:31;;;;;;;;;;;;;;;;;;;:36;;;;;:41;;;64684:56;64681:95;;;64763:1;64756:8;;;;;64681:95;-1:-1:-1;;;;;64808:23:0;;;;;;:16;:23;;;;;:31;;64793:108;;64808:23;64832:6;;64808:31;;;;;;;;;;;;;;;;;;;;;:37;-1:-1:-1;;;;;64847:23:0;;;;:16;:23;;;;;;;:31;;-1:-1:-1;;;64808:37:0;;;;;;64871:6;;64847:31;;;;;;;;;;;;;;:34;:31;;;;;:34;;;-1:-1:-1;;;;;64883:13:0;;;;:6;:13;;;;;;;:17;;64793:14;:108::i;:::-;64786:115;64519:390;-1:-1:-1;;;64519:390:0:o;50761:584::-;2111:11;;;;2103:55;;;;;-1:-1:-1;;;2103:55:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2103:55:0;;;;;;;;;;;;;;;2250:5;2236:19;;-1:-1:-1;;2236:19:0;;;38971:7;;2236:19;38971:7;38970:8;38962:40;;;;;-1:-1:-1;;;38962:40:0;;;;;;;;;;;;-1:-1:-1;;;38962:40:0;;;;;;;;;;;;;;;50895:10;63109:25;63137:16;:14;:16::i;:::-;63109:44;-1:-1:-1;63237:21:0;;63234:397;;63275:20;:40;;;63347:26;:24;:26::i;:::-;63330:14;:43;-1:-1:-1;;;;;63454:22:0;;;63450:170;;63517:16;63524:8;63517:6;:16::i;:::-;-1:-1:-1;;;;;63497:17:0;;;;;;:7;:17;;;;;;;;:36;;;;63552:22;:32;;;:52;;;63450:170;50923:28;;:::i;:::-;-1:-1:-1;50954:79:0;;;;;;;;50984:10;-1:-1:-1;50977:18:0;;;:6;:18;;;;;;;:25;;;;;;50954:79;;;;51009:18;;;;;;50977:25;51009:22;;50954:79;;;;;;;51054:10;51046:49;;;;;-1:-1:-1;;;51046:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;51131:1;51114:7;:14;;;:18;;;51106:53;;;;;-1:-1:-1;;;51106:53:0;;;;;;;;;;;;-1:-1:-1;;;51106:53:0;;;;;;;;;;;;;;;51192:15;51178:7;:11;;;:29;51170:78;;;;-1:-1:-1;;;51170:78:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51261:76;51273:10;51285:6;51293:1;51296:7;51305:31;51261:11;:76::i;:::-;-1:-1:-1;;2416:11:0;:18;;-1:-1:-1;;2416:18:0;2430:4;2416:18;;;-1:-1:-1;;50761:584:0:o;36787:27::-;;;;;;:::o;57546:1869::-;57653:7;57702:12;57686;:28;;57678:75;;;;-1:-1:-1;;;57678:75:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57814:17;57834:41;57854:6;57862:12;57834:19;:41::i;:::-;57814:61;-1:-1:-1;57889:14:0;57886:53;;57926:1;57919:8;;;;;57886:53;57949:19;;:::i;:::-;-1:-1:-1;;;;;57971:24:0;;;;;;:16;:24;;;;;:35;;57996:9;;57971:35;;;;;;;;;;;;;;57949:57;;;;;;;;57971:35;;;;;;;57949:57;;;;;;;;;;;;-1:-1:-1;;;57949:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58088:11;;57949:57;;-1:-1:-1;58088:11:0;58126:39;58142:12;58088:11;58126:15;:39::i;:::-;58110:55;;58176:19;;:::i;:::-;58198:12;58211:5;58198:19;;;;;;;;;;;;;;;;58176:41;;;;;;;;58198:19;;;;;;;58176:41;;;;;;;;;;;;-1:-1:-1;;;58176:41:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;58198:19:0;58471:16;;;58468:315;;;58503:19;;:::i;:::-;58525:12;58538;:5;58548:1;58538:12;:9;:12;:::i;:::-;58525:26;;;;;;;;;;;;;;;;;58503:48;;;;;;;;58525:26;;;;;;;58503:48;;;;;;;;;;;;-1:-1:-1;;;58503:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58590:10;;;58503:48;;-1:-1:-1;58575:26:0;;;:14;:26;:::i;:::-;58566:35;;58624:24;58638:6;:9;;;58624:6;:9;;;:13;;:24;;;;:::i;:::-;58616:32;;58468:315;;;;58707:10;;;;58690:28;;:12;;:28;:16;:28;:::i;:::-;58681:37;;58741:30;58761:6;:9;;;58741:15;:19;;:30;;;;:::i;:::-;58733:38;;58468:315;58901:9;;;;58924:11;;58921:196;;59039:66;59053:51;59097:6;59053:39;59063:28;59080:6;:10;;;59063:12;:16;;:28;;;;:::i;:::-;59053:5;;:39;:9;:39;:::i;:51::-;59039:9;;:66;:13;:66;:::i;:::-;59027:78;;58921:196;59215:67;59231:50;59255:24;59269:6;:9;;;59255;:13;;:24;;;;:::i;:::-;59231:12;;;;:16;;;:50;:16;:50;:::i;:::-;59215:11;;:15;;;:67;:15;:67;:::i;:::-;59201:81;;;;;;;;;:11;59296:16;;;59293:115;;-1:-1:-1;;59343:11:0;;59335:20;;;-1:-1:-1;59328:27:0;;-1:-1:-1;;;;;59328:27:0;59293:115;59395:1;59388:8;;;;;;;;;;57546:1869;;;;;:::o;36842:26::-;;;;:::o;51479:760::-;2111:11;;;;2103:55;;;;;-1:-1:-1;;;2103:55:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2103:55:0;;;;;;;;;;;;;;;2250:5;2236:19;;-1:-1:-1;;2236:19:0;;;38971:7;;2236:19;38971:7;38970:8;38962:40;;;;;-1:-1:-1;;;38962:40:0;;;;;;;;;;;;-1:-1:-1;;;38962:40:0;;;;;;;;;;;;;;;51618:10;63109:25;63137:16;:14;:16::i;:::-;63109:44;-1:-1:-1;63237:21:0;;63234:397;;63275:20;:40;;;63347:26;:24;:26::i;:::-;63330:14;:43;-1:-1:-1;;;;;63454:22:0;;;63450:170;;63517:16;63524:8;63517:6;:16::i;:::-;-1:-1:-1;;;;;63497:17:0;;;;;;:7;:17;;;;;;;;:36;;;;63552:22;:32;;;:52;;;63450:170;51646:28;;:::i;:::-;-1:-1:-1;51677:79:0;;;;;;;;51707:10;-1:-1:-1;51700:18:0;;;:6;:18;;;;;;;:25;;;;;;51677:79;;;;51732:18;;;;;51700:25;51732:22;;;;51677:79;;;;;;;;51789:25;51802:11;51789:12;:25::i;:::-;51767:47;;51890:1;51873:7;:14;;;:18;;;51865:48;;;;;-1:-1:-1;;;51865:48:0;;;;;;;;;;;;-1:-1:-1;;;51865:48:0;;;;;;;;;;;;;;;51946:15;51932:7;:11;;;:29;51924:54;;;;;-1:-1:-1;;;51924:54:0;;;;;;;;;;;;-1:-1:-1;;;51924:54:0;;;;;;;;;;;;;;;52011:7;:11;;;51997;:25;51989:65;;;;;-1:-1:-1;;;51989:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;52088:3;;52073:11;:18;;52065:74;;;;-1:-1:-1;;;52065:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52152:79;52164:10;52176:1;52179:11;52192:7;52201:29;52152:11;:79::i;:::-;-1:-1:-1;;2416:11:0;:18;;-1:-1:-1;;2416:18:0;2430:4;2416:18;;;-1:-1:-1;;;51479:760:0:o;65412:127::-;65519:12;;-1:-1:-1;;;;;65519:12:0;65412:127;:::o;37763:46::-;;;;;;;;;;;;;:::o;56786:509::-;-1:-1:-1;;;;;56910:22:0;;56869:7;56910:22;;;:14;:22;;;;;;56946:10;56943:49;;56979:1;56972:8;;;;;56943:49;57002:22;;:::i;:::-;-1:-1:-1;;;;;57027:24:0;;;;;;:16;:24;;;;;:31;;57052:5;;57027:31;;;;;;;;;;;;;;;57002:56;;;;;;;;57027:31;;;;;;;57002:56;;;;;;;;;;;;-1:-1:-1;;;57002:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;57086:82:0;;57105:62;;57132:33;;:15;;:33;:19;:33;:::i;:::-;57105:15;;;;:19;;;:62;:19;:62;:::i;:::-;57086:14;;:18;;;:82;:18;:82;:::i;:::-;57069:99;;;;;;;;;:14;57182:18;;;57179:68;;;57234:1;57217:18;;57179:68;57272:14;57264:23;;;56786:509;-1:-1:-1;;;56786:509:0:o;36635:26::-;;;-1:-1:-1;;;;;36635:26:0;;:::o;37366:29::-;;;;:::o;65832:169::-;65916:7;65948:45;65963:15;65980:12;;65948:14;:45::i;:::-;65941:52;;65832:169;:::o;36967:49::-;;;;;;;;;;;;;:::o;36875:27::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;36875:27:0;;;;;;;;;:::o;37650:57::-;;;;;;;;;;;;;:::o;53905:264::-;38971:7;;;;38970:8;38962:40;;;;;-1:-1:-1;;;38962:40:0;;;;;;;;;;;;-1:-1:-1;;;38962:40:0;;;;;;;;;;;;;;;54003:5;39229:29;;:::i;:::-;-1:-1:-1;;;;;;39261:13:0;;;;;;:6;:13;;;;;;;;39229:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39293:19;;;:54;;;;;39335:8;:12;;;39316:15;:31;;39293:54;39285:91;;;;;-1:-1:-1;;;39285:91:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;39420:1;39395:22;39411:5;39395:15;:22::i;:::-;:26;39387:67;;;;;-1:-1:-1;;;39387:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;54026:16;54036:5;54026:9;:16::i;:::-;54119:42;;;54134:9;54119:42;;54145:15;54119:42;;;;;;-1:-1:-1;;;;;54119:42:0;;;;;;;;;;;39013:1;;53905:264;:::o;37209:20::-;;;;;;;;;;;;;;;-1:-1:-1;;37209:20:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61635:1171;61728:7;61777:12;61761;:28;;61753:75;;;;-1:-1:-1;;;61753:75:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61857:11;;61841:13;61901:36;61917:12;61857:11;61901:15;:36::i;:::-;61879:58;;61950:18;;:::i;:::-;61971:12;61984:11;61971:25;;;;;;;;;;;;;;;;;61950:46;;;;;;;;61971:25;;;;;;;61950:46;;;;;;;;;;;;-1:-1:-1;;;61950:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;62117:24:0;-1:-1:-1;62114:63:0;;;62164:1;62157:8;;;;;;;62114:63;62189:13;62220:19;;;62217:458;;;62255:22;;:::i;:::-;62280:12;62293:18;:11;62309:1;62293:18;:15;:18;:::i;:::-;62280:32;;;;;;;;;;;;;;;;;62255:57;;;;;;;;62280:32;;;;;;;62255:57;;;;;;;;;;;;-1:-1:-1;;;62255:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62330:9;;;62255:57;;-1:-1:-1;62330:26:0;62327:169;;62385:95;62451:28;62469:5;:9;;;62451;:13;;;:17;;:28;;;;:::i;:::-;62385:61;62419:26;62436:5;:8;;;62419:9;:12;;;:16;;:26;;;;:::i;:::-;62403:9;;;;62386:27;;:12;;:27;:16;:27;:::i;:::-;62385:33;:61;:33;:61;:::i;:95::-;62377:103;;62327:169;62217:458;;;;62530:12;62517:5;:9;;;:25;62513:162;;62566:97;62635:27;62652:5;:9;;;62635:12;:16;;:27;;;;:::i;:::-;62566:64;62600:29;62620:5;:8;;;62600:15;:19;;:29;;;;:::i;:::-;62584:9;;;;62567:27;;:12;;:27;:16;:27;:::i;62566:97::-;62558:105;;62513:162;62761:37;62771:5;62778:19;62791:5;62778;:8;;;:12;;:19;;;;:::i;:::-;62761:9;:37::i;:::-;62754:44;61635:1171;-1:-1:-1;;;;;;61635:1171:0:o;4606:19::-;;;;;;-1:-1:-1;;;;;4606:19:0;;:::o;65618:117::-;36700:6;65618:117;:::o;37457:36::-;;;;:::o;49799:787::-;2111:11;;;;2103:55;;;;;-1:-1:-1;;;2103:55:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2103:55:0;;;;;;;;;;;;;;;2250:5;2236:19;;-1:-1:-1;;2236:19:0;;;38971:7;;2236:19;38971:7;38970:8;38962:40;;;;;-1:-1:-1;;;38962:40:0;;;;;;;;;;;;-1:-1:-1;;;38962:40:0;;;;;;;;;;;;;;;49946:10;63109:25;63137:16;:14;:16::i;:::-;63109:44;-1:-1:-1;63237:21:0;;63234:397;;63275:20;:40;;;63347:26;:24;:26::i;:::-;63330:14;:43;-1:-1:-1;;;;;63454:22:0;;;63450:170;;63517:16;63524:8;63517:6;:16::i;:::-;-1:-1:-1;;;;;63497:17:0;;;;;;:7;:17;;;;;;;;:36;;;;63552:22;:32;;;:52;;;63450:170;49974:19;49996:25;50009:11;49996:12;:25::i;:::-;49974:47;;50070:28;;:::i;:::-;-1:-1:-1;50101:79:0;;;;;;;;50131:10;-1:-1:-1;50124:18:0;;;:6;:18;;;;;;;:25;;;;;;50101:79;;;;50156:18;;;;;;50124:25;50156:22;;50101:79;;;;;;;50201:10;50193:49;;;;;-1:-1:-1;;;50193:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;50261:14;;:19;;;50253:57;;;;;-1:-1:-1;;;50253:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;50345:15;50331:11;:29;50323:80;;;;-1:-1:-1;;;50323:80:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50437:3;;50422:11;:18;;50414:74;;;;-1:-1:-1;;;50414:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50501:77;50513:10;50525:6;50533:11;50546:7;50555:22;50501:11;:77::i;:::-;-1:-1:-1;;2416:11:0;:18;;-1:-1:-1;;2416:18:0;2430:4;2416:18;;;-1:-1:-1;;;;49799:787:0:o;63804:395::-;63865:10;63109:25;63137:16;:14;:16::i;:::-;63109:44;-1:-1:-1;63237:21:0;;63234:397;;63275:20;:40;;;63347:26;:24;:26::i;:::-;63330:14;:43;-1:-1:-1;;;;;63454:22:0;;;63450:170;;63517:16;63524:8;63517:6;:16::i;:::-;-1:-1:-1;;;;;63497:17:0;;;;;;:7;:17;;;;;;;;:36;;;;63552:22;:32;;;:52;;;63450:170;63918:10;63893:14;63910:19;;;:7;:19;;;;;;63944:10;;63940:252;;63979:10;63993:1;63971:19;;;:7;:19;;;;;:23;64009:12;;:45;;-1:-1:-1;;;;;64009:12:0;;;;64047:6;64009:25;:45::i;:::-;64107:10;64095:23;;;;:11;:23;;;;;;:35;;64123:6;64095:35;:27;:35;:::i;:::-;64081:10;64069:23;;;;:11;:23;;;;;;;;;:61;;;;64150:30;;;;;;;64081:10;;64150:30;;;;;;;;;63940:252;63641:1;63804:395;;:::o;49492:124::-;49534:26;;:::i;:::-;49571:37;49591:1;49595:5;49602;49571:11;:37::i;:::-;49492:124;:::o;39828:425::-;-1:-1:-1;;;;;40040:21:0;;39932:11;40040:21;;;:14;:21;;;;;;39932:11;;;;40075;40072:58;;-1:-1:-1;40110:1:0;;-1:-1:-1;40110:1:0;;-1:-1:-1;40110:1:0;;-1:-1:-1;40102:16:0;;40072:58;40140:18;;:::i;:::-;-1:-1:-1;;;;;40161:23:0;;;;;;:16;:23;;;;;:31;;40185:6;;40161:31;;;;;;;;;;;;;;;40140:52;;;;;;;;40161:31;;;;;;;40140:52;;;;;;;;;;;;;-1:-1:-1;;;40140:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;40140:52:0;;-1:-1:-1;40140:52:0;-1:-1:-1;;;39828:425:0;;;;;;:::o;37500:33::-;;;;:::o;37076:47::-;;;;;;;;;;;;;;;;;;;;;;;;;:::o;66227:765::-;66412:17;;66301:7;;66444:16;66440:76;;-1:-1:-1;;66484:20:0;;66477:27;;66440:76;66604:31;66638:62;66653:46;66684:14;;66653:26;:24;:26::i;:46::-;66638:10;;;:62;:14;:62;:::i;:::-;66604:96;-1:-1:-1;66799:33:0;66835:49;66604:96;66872:11;66835:49;:36;:49;:::i;:::-;66933:20;;66799:85;;-1:-1:-1;66933:51:0;;66799:85;66933:51;:24;:51;:::i;:::-;66926:58;;;;;66227:765;:::o;37540:39::-;;;;:::o;53576:103::-;53626:21;53636:10;53626:9;:21::i;:::-;53658:13;:11;:13::i;37328:31::-;;;;:::o;36713:42::-;36747:8;36713:42;:::o;36762:18::-;;;;:::o;37023:46::-;;;;;;;;;;;;;;;:::o;13661:136::-;13719:7;13746:43;13750:1;13753;13746:43;;;;;;;;;;;;;;;;;:3;:43::i;28543:167::-;28636:7;28668:34;28685:1;28688;26874:4;28668:16;:34::i;13205:181::-;13263:7;13295:5;;;13319:6;;;;13311:46;;;;;-1:-1:-1;;;13311:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;6084:95;6128:7;6155:5;;;;;;;;;-1:-1:-1;;;;;6155:5:0;-1:-1:-1;;;;;6155:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;6155:16:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;6155:16:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;6155:16:0;;-1:-1:-1;6084:95:0;:::o;59671:1329::-;59773:7;59798:22;;:::i;:::-;59823:6;59798:31;;59891:21;59915:26;59928:9;:12;;;59915;:26::i;:::-;59891:50;-1:-1:-1;60043:9:0;60039:833;60062:3;60058:1;:7;60039:833;;;60102:23;:13;36700:6;60102:23;:17;:23;:::i;:::-;60086:39;-1:-1:-1;60140:13:0;60257:18;;;60254:215;;;60311:2;60295:18;;60254:215;;;-1:-1:-1;60426:27:0;;;;:12;:27;;;;;;;;60254:215;60600:80;60619:60;60646:31;60664:9;:12;;;60646:13;:17;;:31;;;;:::i;:::-;60619:15;;;;:19;;;:60;:19;:60;:::i;:::-;60600:14;;:18;;;:80;:18;:80;:::i;:::-;60583:97;;;;;;;;60698:19;;;60695:63;;;60737:5;;;60695:63;60790:15;;;;:27;;:19;;60810:6;60790:27;:19;:27;:::i;:::-;60772:45;;;;;;:15;;;:45;-1:-1:-1;60832:12:0;;;:28;;;60067:3;;60039:833;;;;60905:1;60888:9;:14;;;:18;;;60884:68;;;60939:1;60922:18;;60884:68;-1:-1:-1;60977:14:0;60969:23;;;59671:1329;-1:-1:-1;;;59671:1329:0:o;15516:132::-;15574:7;15601:39;15605:1;15608;15601:39;;;;;;;;;;;;;;;;;:3;:39::i;14577:471::-;14635:7;14880:6;14876:47;;-1:-1:-1;14910:1:0;14903:8;;14876:47;14947:5;;;14951:1;14947;:5;:1;14971:5;;;;;:10;14963:56;;;;-1:-1:-1;;;14963:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52571:909;2111:11;;;;2103:55;;;;;-1:-1:-1;;;2103:55:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2103:55:0;;;;;;;;;;;;;;;2250:5;2236:19;;-1:-1:-1;;2236:19:0;;;52667:5;;63137:16;:14;:16::i;:::-;63109:44;-1:-1:-1;63237:21:0;;63234:397;;63275:20;:40;;;63347:26;:24;:26::i;:::-;63330:14;:43;-1:-1:-1;;;;;63454:22:0;;;63450:170;;63517:16;63524:8;63517:6;:16::i;:::-;-1:-1:-1;;;;;63497:17:0;;;;;;:7;:17;;;;;;;;:36;;;;63552:22;:32;;;:52;;;63450:170;52690:28;;:::i;:::-;-1:-1:-1;52721:71:0;;;;;;;;-1:-1:-1;;;;;52769:13:0;;-1:-1:-1;52769:13:0;;;:6;:13;;;;;;;:20;;;;;;52721:71;;;;52742:13;;;;;;52769:20;52742:17;;52721:71;;;;;;;52811:15;:30;;;:41;;-1:-1:-1;52845:7:0;;;;52811:41;52803:76;;;;;-1:-1:-1;;;52803:76:0;;;;;;;;;;;;-1:-1:-1;;;52803:76:0;;;;;;;;;;;;;;;52915:1;52898:7;:14;;;:18;;;52890:62;;;;;-1:-1:-1;;;52890:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;52989:14;;52981:23;;53017:32;;:::i;:::-;-1:-1:-1;53052:34:0;;;;;;;;-1:-1:-1;53052:34:0;;;;;;;;;;-1:-1:-1;;;;;53097:13:0;;;;:6;:13;;;;;;:27;;;;53052:34;53097:27;;;;-1:-1:-1;;;;;53097:27:0;-1:-1:-1;;;;;;53097:27:0;;;;;;;;;;;;;;;;53289:7;;;;53285:79;;53312:40;53324:5;53331:7;53340:11;53312;:40::i;:::-;53376:12;;:39;;-1:-1:-1;;;;;53376:12:0;53402:5;53409;53376:39;:25;:39;:::i;:::-;53433;;;;;;53456:15;53433:39;;;;;;-1:-1:-1;;;;;53433:39:0;;;;;;;;;;;-1:-1:-1;;2416:11:0;:18;;-1:-1:-1;;2416:18:0;2430:4;2416:18;;;-1:-1:-1;;;;52571:909:0:o;64917:434::-;65044:7;65085:8;65072:10;:21;65069:34;;;-1:-1:-1;65102:1:0;65095:8;;65069:34;65161:20;65184:24;:8;65197:10;65184:24;:12;:24;:::i;:::-;65161:47;;65257:9;65269:55;65300:23;65310:12;65300:9;:23::i;:::-;65277:17;:10;;;;65288:5;65277:17;:10;:17;:::i;:::-;65269:26;;;:55;:30;:55;:::i;48332:1076::-;48544:30;;:::i;:::-;-1:-1:-1;48577:63:0;;;;;;;;;48600:17;;48577:63;;;;;;;;48624:14;;;;48577:63;;;;48754:36;;:20;48782:6;48754:36;:20;:36;:::i;:::-;48735:55;;;;;;;;48804:16;;48801:74;;48836:13;;;:27;;;48801:74;-1:-1:-1;;;;;48885:13:0;;;;;;:6;:13;;;;;;;;:25;;;;;;;;;-1:-1:-1;;;;;48885:25:0;-1:-1:-1;;;;;;48885:25:0;;;;;;;;;;;;;;;49164:41;48892:5;49183:10;48901:9;49164:11;:41::i;:::-;49221:11;;49218:102;;49249:12;;:59;;-1:-1:-1;;;;;49249:12:0;49279:5;49294:4;49301:6;49249:59;:29;:59;:::i;:::-;49375:7;49337:63;;;;;;;;49360:13;;;;;49337:63;;;;;;;;;;;;;49384:15;49337:63;;;;;-1:-1:-1;;;;;49337:63:0;;;;;;;;;;;;;48332:1076;;;;;;:::o;56031:565::-;-1:-1:-1;;;;;56205:21:0;;56140:7;56205:21;;;:14;:21;;;;;;56140:7;;;56237:331;56260:3;56256:1;:7;56237:331;;;56295:3;56288;:10;56285:54;;56318:5;;56285:54;56353:11;56367:28;56393:1;56368:19;56385:1;56368:12;:3;56376;56368:12;:7;:12;:::i;:::-;:16;:19;:16;:19;:::i;56367:28::-;-1:-1:-1;;;;;56413:23:0;;;;;;:16;:23;;;;;:28;;56353:42;;-1:-1:-1;56449:6:0;;56353:42;;56413:28;;;;;;;;;;;;;;;;:32;;;:42;56410:147;;56481:3;56475:9;;56410:147;;;56531:10;:3;56539:1;56531:10;:7;:10;:::i;:::-;56525:16;;56410:147;-1:-1:-1;56265:3:0;;56237:331;;;-1:-1:-1;56585:3:0;;56031:565;-1:-1:-1;;;;56031:565:0:o;55186:607::-;55295:7;;55386:9;55295:7;55460:305;55483:3;55479:1;:7;55460:305;;;55518:3;55511;:10;55507:38;;55540:5;;55507:38;55560:11;55574:28;55600:1;55575:19;55592:1;55575:12;:3;55583;55575:12;:7;:12;:::i;55574:28::-;55560:42;;55646:6;55621:12;55634:3;55621:17;;;;;;;;;;;;;;;;;;:21;;;:31;55617:137;;55678:3;55672:9;;55617:137;;;55728:10;:3;55736:1;55728:10;:7;:10;:::i;:::-;55722:16;;55617:137;-1:-1:-1;55488:3:0;;55460:305;;24390:568;24446:6;24690:1;:6;;24695:1;24690:6;24686:47;;;-1:-1:-1;24720:1:0;24713:8;;24686:47;24755:1;:7;;-1:-1:-1;;24755:7:0;:27;;;;-1:-1:-1;24766:16:0;;;;-1:-1:-1;;;;;;24766:16:0;24755:27;24753:30;24745:82;;;;-1:-1:-1;;;24745:82:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24840:8;24855:1;24851;:5;24840:16;;24884:1;24875:10;;24879:1;24875:5;;:1;:5;;;;;;;;:10;;;24867:62;;;;-1:-1:-1;;;24867:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25954:218;26010:6;26040:5;;;26065:6;;;;;-1:-1:-1;26065:6:0;;;:16;;;26080:1;26075:6;;:1;:6;;;;26065:16;26064:38;;;;26091:1;26087;:5;;;:14;;;;;26100:1;26096:5;;:1;:5;;;26087:14;26056:87;;;;-1:-1:-1;;;26056:87:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54784:145;54867:7;54899:22;36700:6;54899:12;:2;36700:6;54899:12;:6;:12;:::i;33597:138::-;33682:7;33718:1;33714;:5;:13;;33726:1;33714:13;;;-1:-1:-1;33722:1:0;33597:138;-1:-1:-1;33597:138:0:o;20894:176::-;21003:58;;;-1:-1:-1;;;;;21003:58:0;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;21003:58:0;;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;20977:85:0;;20996:5;;20977:18;:85::i;40693:7268::-;40863:25;;:::i;:::-;40899;;:::i;:::-;41021:11;;40935:20;;;;-1:-1:-1;;;;;41048:19:0;;;41045:2388;;41194:15;41177:10;:14;;;:32;:57;;;;;41233:1;41213:10;:17;;;:21;;;41177:57;41174:261;;;41275:17;;:38;;:21;;36747:8;41275:38;:21;:38;:::i;:::-;41254:59;;;;;;:18;;;;:59;;;;41382:14;;;41352:67;;41382:35;;41401:15;41382:35;:18;:35;:::i;41352:67::-;41332:87;;;;;;;;41174:261;41469:15;41452:10;:14;;;:32;:57;;;;;41508:1;41488:10;:17;;;:21;;;41452:57;41449:261;;;41550:17;;:38;;:21;;36747:8;41550:38;:21;:38;:::i;:::-;41529:59;;;;;;:18;;;;:59;;;;41657:14;;;41627:67;;41657:35;;41676:15;41657:35;:18;:35;:::i;:::-;41627:18;;;;:22;;;:67;:22;:67;:::i;:::-;41607:87;;;;;;;;41449:261;-1:-1:-1;;;;;41890:21:0;;41873:14;41890:21;;;:14;:21;;;;;;41929:11;41926:92;;-1:-1:-1;;;;;41960:23:0;;;;;;:16;:23;;;;;;;;27:10:-1;;39:1;23:18;;;45:23;;41960:42:0;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;41960:42:0;;;-1:-1:-1;;;41960:42:0;;;;;;;-1:-1:-1;;;;;;41960:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41926:92;42078:17;42098:67;42113:12;:18;;;42133:15;42150:10;:14;;;42098;:67::i;:::-;42078:87;;42180:28;42211:32;42233:9;42211:17;;:21;;:32;;;;:::i;:::-;42180:63;-1:-1:-1;42261:10:0;;42258:251;;-1:-1:-1;;;;;42326:23:0;;42291:17;42326:23;;;:16;:23;;;;;:31;;42311:105;;42326:23;42350:6;;42326:31;;;;;;;;;;;;;;;;:37;;;;;;;;;;;;42365:16;:23;42382:5;-1:-1:-1;;;;;42365:23:0;-1:-1:-1;;;;;42365:23:0;;;;;;;;;;;;42389:6;42365:31;;;;;;;;;;;;;;;;;;:34;;;42401:10;:14;;;42311;:105::i;:::-;42291:125;-1:-1:-1;42458:35:0;:20;42291:125;42458:35;:24;:35;:::i;:::-;42435:58;;42258:251;;42523:17;:40;;;42604:13;:6;42615:1;42604:13;:10;:13;:::i;:::-;-1:-1:-1;;;;;42580:21:0;;;;;;:14;:21;;;;;;;;:37;;;;42650:15;42632;;;:33;;;42699:12;42680:16;;;:31;;;42797:23;;;:16;:23;;;;;27:10:-1;;39:1;23:18;;;45:23;;42797:42:0;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;42797:42:0;;;-1:-1:-1;;;42797:42:0;;;;;;-1:-1:-1;;;;;;42797:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43132:14;;;;43119:28;;:12;:28;;;;;;43165:14;;;;43119:28;;;;-1:-1:-1;43165:19:0;43162:260;;43226:10;:14;;;43208:10;:14;;;:32;43204:203;;;43281:13;43265:29;;43204:203;;;43372:14;;;;;43359:28;;;;:12;:28;;;;;;;;;;-1:-1:-1;43204:203:0;41045:2388;;;;43445:22;;:::i;:::-;-1:-1:-1;43470:66:0;;;;;;;;-1:-1:-1;43470:66:0;;;;;;;43500:15;43470:66;;;;;;;43522:12;43470:66;;;;43550:9;;43547:71;;43587:12;43600:5;43587:19;;;;;;;;;;;;;;;;;43575:31;;;;;;;;43587:19;;;;;;;43575:31;;;;;;;;;;;;-1:-1:-1;;;43575:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;43547:71:0;43653:12;;;;43892:29;;:::i;:::-;-1:-1:-1;43924:64:0;;;;;;;;-1:-1:-1;43924:64:0;;;;;;;;;43954:12;;;;;43924:64;;;;;;;;43973:13;;;;43924:64;;;;44066:12;;43924:64;;-1:-1:-1;44048:15:0;:30;44045:169;;;44107:95;44168:33;44188:9;:12;;;44168:15;:19;;:33;;;;:::i;:::-;44107:56;44131:31;44148:9;:13;;;44131:12;:16;;:31;;;;:::i;:::-;44107:23;:56::i;:95::-;44094:108;;44045:169;44438:21;44462:28;44475:14;44462:12;:28::i;:::-;44438:52;-1:-1:-1;44506:9:0;44501:1568;44525:3;44521:1;:7;44501:1568;;;44734:23;:13;36700:6;44734:23;:17;:23;:::i;:::-;44718:39;-1:-1:-1;44772:13:0;44823:15;44807:31;;44804:178;;;44874:15;44858:31;;44804:178;;;-1:-1:-1;44939:27:0;;;;:12;:27;;;;;;;;44804:178;44996:16;45015:62;45042:33;:13;45060:14;45042:33;:17;:33;:::i;45015:62::-;45109:14;;44996:81;;-1:-1:-1;45109:29:0;;:18;;44996:81;45109:29;:18;:29;:::i;:::-;45092:46;;;;;;;;45171:15;;;;:27;;:19;45191:6;45171:27;:19;:27;:::i;:::-;45153:45;;;;;;:15;;;:45;45248:14;;45265:1;45248:18;;;45245:75;;;45303:1;45286:18;;45245:75;45405:1;45387:9;:15;;;:19;;;45384:77;;;45444:1;45426:15;;;:19;45384:77;45492:13;45475:30;;45535:13;45520:9;:12;;:28;;;;;45579:88;45604:62;45627:38;45645:16;:19;;;45627:13;:17;;:38;;;;:::i;:::-;45604:10;;:62;:22;:62;:::i;:::-;45579:20;;;;;:88;:24;:88;:::i;:::-;45563:13;;;:104;45785:12;:5;45795:1;45785:12;:9;:12;:::i;:::-;45777:20;;45832:15;45815:13;:32;45812:246;;;-1:-1:-1;;45884:12:0;45868:13;;;:28;45915:5;;45812:246;46014:12;27:10:-1;;39:1;23:18;;45:23;;-1:-1;46014:28:0;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;46014:28:0;;;-1:-1:-1;;;46014:28:0;;;;;;;-1:-1:-1;;;;;;46014:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;44530:3:0;;44501:1568;;;-1:-1:-1;46081:11:0;:19;;;-1:-1:-1;;;;;46167:19:0;;;46164:547;;46363:63;46383:42;46406:12;:18;;;46383:12;:18;;;:22;;;;:42;;;;:::i;:::-;46363:15;;;;:19;;;:63;:19;:63;:::i;:::-;46345:81;;;;;;:15;;;:81;46499:17;;46477;;46458:60;;46477:40;;:21;;;;:40;:21;:40;:::i;:::-;46458:14;;:18;;;:60;:18;:60;:::i;:::-;46441:77;;;;;;;;46536:15;;;;46441:14;46536:19;;;46533:78;;;46594:1;46576:15;;;:19;46533:78;46645:1;46628:9;:14;;;:18;;;46625:75;;;46683:1;46666:18;;46625:75;46818:12;27:10:-1;;39:1;23:18;;45:23;;-1:-1;46818:28:0;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;46818:28:0;;;-1:-1:-1;;;46818:28:0;;;;;;;-1:-1:-1;;;;;;46818:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;46862:19:0;;;46859:1095;;47106:15;47089:10;:14;;;:32;47086:468;;;47247:37;47265:12;:18;;;47247:13;:17;;;;:37;;;;:::i;:::-;47231:53;;47324:10;:14;;;47306:10;:14;;;:32;47303:173;;;47379:37;47397:12;:18;;;47379:13;:17;;;;:37;;;;:::i;:::-;47363:53;;47303:173;47507:14;;;;;47494:28;;;;:12;:28;;;;;;:44;;-1:-1:-1;;;;;;47494:44:0;-1:-1:-1;;;;;47494:44:0;;;;;;;;47086:468;47588:15;47571:10;:14;;;:32;47568:375;;;47644:10;:14;;;47627:10;:14;;;:31;47624:238;;;47698:37;47716:12;:18;;;47698:13;:17;;;;:37;;;;:::i;:::-;47811:14;;;;;47798:28;;;;:12;:28;;;;;;:44;;-1:-1:-1;;;;;;47798:44:0;-1:-1:-1;;;;;47798:44:0;;;;;;;;;-1:-1:-1;47624:238:0;40693:7268;;;;;;;;;;;;;:::o;30775:255::-;30869:7;;30942:17;:1;26874:4;30942:17;:5;:17;:::i;:::-;30930:29;-1:-1:-1;31014:8:0;30930:29;31020:1;31014:8;:5;:8;:::i;:::-;31007:15;30775:255;-1:-1:-1;;;;30775:255:0:o;14134:192::-;14220:7;14256:12;14248:6;;;;14240:29;;;;-1:-1:-1;;;14240:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;14240:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;14292:5:0;;;14134:192::o;29183:312::-;29296:7;;29411:8;:1;29417;29411:8;:5;:8;:::i;:::-;29399:20;-1:-1:-1;29475:12:0;29399:20;29481:5;29475:12;:5;:12;:::i;:::-;29468:19;29183:312;-1:-1:-1;;;;;29183:312:0:o;26417:215::-;26473:6;26503:5;;;26528:6;;;;;-1:-1:-1;26528:6:0;;;:16;;;26543:1;26538:6;;:1;:6;;;;26528:16;26527:38;;;;26554:1;26550;:5;;;:14;;;;;26563:1;26559:5;;:1;:5;;;26550:14;26519:84;;;;-1:-1:-1;;;26519:84:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16178:345;16264:7;16366:12;16359:5;16351:28;;;;-1:-1:-1;;;16351:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27:10:-1;;8:100;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;16351:28:0;;16390:9;16406:1;16402;:5;;;;;;;16178:345;-1:-1:-1;;;;;16178:345:0:o;34683:213::-;34728:6;;34756:17;34771:1;34757:8;:1;34763;34757:8;:5;:8;:::i;34756:17::-;34747:26;;34788:1;34784:5;;34800:89;34811:1;34807;:5;34800:89;;;34833:1;-1:-1:-1;34833:1:0;34853:24;34875:1;34854:15;34833:1;34854:8;:1;34833;34854:8;:5;:8;:::i;34853:24::-;34849:28;;34800:89;;21078:204;21205:68;;;-1:-1:-1;;;;;21205:68:0;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;21205:68:0;;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;21179:95:0;;21198:5;;21179:18;:95::i;:::-;21078:204;;;;:::o;22933:1114::-;23537:27;23545:5;-1:-1:-1;;;;;23537:25:0;;:27::i;:::-;23529:71;;;;;-1:-1:-1;;;23529:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;23674:12;23688:23;23723:5;-1:-1:-1;;;;;23715:19:0;23735:4;23715:25;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;23715:25:0;;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;23673:67:0;;;;23759:7;23751:52;;;;;-1:-1:-1;;;23751:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23820:17;;:21;23816:224;;23962:10;23951:30;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;23951:30:0;23943:85;;;;-1:-1:-1;;;23943:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25432:271;25488:6;25515:1;:6;;25520:1;25515:6;;25507:51;;;;;-1:-1:-1;;;25507:51:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25579:1;:7;;-1:-1:-1;;25579:7:0;:27;;;;-1:-1:-1;25590:16:0;;;;-1:-1:-1;;;;;;25590:16:0;25579:27;25577:30;25569:76;;;;-1:-1:-1;;;25569:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25658:8;25673:1;25669:5;;:1;:5;;;;;;;;;25432:271;-1:-1:-1;;;;25432:271:0:o;27932:140::-;28015:7;28047:17;:1;26874:4;28047:17;:5;:17;:::i;18484:619::-;18544:4;19012:20;;18855:66;19052:23;;;;;;:42;;-1:-1:-1;;19079:15:0;;;18484:619;-1:-1:-1;;18484:619:0:o;35914:32891::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;-1:-1:-1;35914:32891:0;;;;;;;;:::o

Swarm Source

bzzr://85e3f238d32bc335c149534b55f8b5ad9f7f0a75e0f25845c4d0885cf356b13a
Block Transaction Difficulty Gas Used Reward
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.

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.