Overview
ETH Balance
0 ETH
Eth Value
$0.00Token Holdings
Latest 25 from a total of 66,678 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Process Expired ... | 21385197 | 8 mins ago | IN | 0 ETH | 0.00211869 | ||||
Process Expired ... | 21385065 | 35 mins ago | IN | 0 ETH | 0.00250339 | ||||
Lock | 21384911 | 1 hr ago | IN | 0 ETH | 0.00366684 | ||||
Process Expired ... | 21384821 | 1 hr ago | IN | 0 ETH | 0.00269123 | ||||
Lock | 21384584 | 2 hrs ago | IN | 0 ETH | 0.00287276 | ||||
Process Expired ... | 21384377 | 2 hrs ago | IN | 0 ETH | 0.00261238 | ||||
Process Expired ... | 21383982 | 4 hrs ago | IN | 0 ETH | 0.00252913 | ||||
Lock | 21383816 | 4 hrs ago | IN | 0 ETH | 0.00344932 | ||||
Get Reward | 21383681 | 5 hrs ago | IN | 0 ETH | 0.00330044 | ||||
Process Expired ... | 21383645 | 5 hrs ago | IN | 0 ETH | 0.0031683 | ||||
Lock | 21383642 | 5 hrs ago | IN | 0 ETH | 0.00288036 | ||||
Process Expired ... | 21383640 | 5 hrs ago | IN | 0 ETH | 0.00284965 | ||||
Process Expired ... | 21383570 | 5 hrs ago | IN | 0 ETH | 0.00210266 | ||||
Process Expired ... | 21383556 | 5 hrs ago | IN | 0 ETH | 0.00274153 | ||||
Lock | 21383536 | 5 hrs ago | IN | 0 ETH | 0.00307872 | ||||
Process Expired ... | 21383208 | 6 hrs ago | IN | 0 ETH | 0.00223215 | ||||
Process Expired ... | 21383198 | 6 hrs ago | IN | 0 ETH | 0.00184579 | ||||
Process Expired ... | 21382966 | 7 hrs ago | IN | 0 ETH | 0.00235438 | ||||
Process Expired ... | 21382824 | 8 hrs ago | IN | 0 ETH | 0.0033043 | ||||
Process Expired ... | 21382801 | 8 hrs ago | IN | 0 ETH | 0.00266856 | ||||
Process Expired ... | 21382800 | 8 hrs ago | IN | 0 ETH | 0.00305623 | ||||
Process Expired ... | 21382705 | 8 hrs ago | IN | 0 ETH | 0.0029896 | ||||
Lock | 21382555 | 8 hrs ago | IN | 0 ETH | 0.00437293 | ||||
Process Expired ... | 21382505 | 9 hrs ago | IN | 0 ETH | 0.00313944 | ||||
Lock | 21382098 | 10 hrs ago | IN | 0 ETH | 0.00424959 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
CvxLockerV2
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2022-03-04 */ // File: contracts\interfaces\MathUtil.sol // SPDX-License-Identifier: MIT pragma solidity 0.6.12; /** * @dev Standard math utilities missing in the Solidity language. */ library MathUtil { /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } } // File: contracts\interfaces\IStakingProxy.sol pragma solidity 0.6.12; interface IStakingProxy { function getBalance() external view returns(uint256); function withdraw(uint256 _amount) external; function stake() external; function distribute() external; } // File: contracts\interfaces\IRewardStaking.sol pragma solidity 0.6.12; interface IRewardStaking { function stakeFor(address, uint256) external; function stake( uint256) external; function withdraw(uint256 amount, bool claim) external; function withdrawAndUnwrap(uint256 amount, bool claim) external; function earned(address account) external view returns (uint256); function getReward() external; function getReward(address _account, bool _claimExtras) external; function extraRewardsLength() external view returns (uint256); function extraRewards(uint256 _pid) external view returns (address); function rewardToken() external view returns (address); function balanceOf(address _account) external view returns (uint256); } // File: contracts\interfaces\BoringMath.sol pragma solidity 0.6.12; /// @notice A library for performing overflow-/underflow-safe math, /// updated with awesomeness from of DappHub (https://github.com/dapphub/ds-math). library BoringMath { function add(uint256 a, uint256 b) internal pure returns (uint256 c) { require((c = a + b) >= b, "BoringMath: Add Overflow"); } function sub(uint256 a, uint256 b) internal pure returns (uint256 c) { require((c = a - b) <= a, "BoringMath: Underflow"); } function mul(uint256 a, uint256 b) internal pure returns (uint256 c) { require(b == 0 || (c = a * b) / b == a, "BoringMath: Mul Overflow"); } function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "BoringMath: division by zero"); return a / b; } function to128(uint256 a) internal pure returns (uint128 c) { require(a <= uint128(-1), "BoringMath: uint128 Overflow"); c = uint128(a); } function to64(uint256 a) internal pure returns (uint64 c) { require(a <= uint64(-1), "BoringMath: uint64 Overflow"); c = uint64(a); } function to32(uint256 a) internal pure returns (uint32 c) { require(a <= uint32(-1), "BoringMath: uint32 Overflow"); c = uint32(a); } function to40(uint256 a) internal pure returns (uint40 c) { require(a <= uint40(-1), "BoringMath: uint40 Overflow"); c = uint40(a); } function to112(uint256 a) internal pure returns (uint112 c) { require(a <= uint112(-1), "BoringMath: uint112 Overflow"); c = uint112(a); } function to224(uint256 a) internal pure returns (uint224 c) { require(a <= uint224(-1), "BoringMath: uint224 Overflow"); c = uint224(a); } function to208(uint256 a) internal pure returns (uint208 c) { require(a <= uint208(-1), "BoringMath: uint208 Overflow"); c = uint208(a); } function to216(uint256 a) internal pure returns (uint216 c) { require(a <= uint216(-1), "BoringMath: uint216 Overflow"); c = uint216(a); } } /// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint128. library BoringMath128 { function add(uint128 a, uint128 b) internal pure returns (uint128 c) { require((c = a + b) >= b, "BoringMath: Add Overflow"); } function sub(uint128 a, uint128 b) internal pure returns (uint128 c) { require((c = a - b) <= a, "BoringMath: Underflow"); } } /// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint64. library BoringMath64 { function add(uint64 a, uint64 b) internal pure returns (uint64 c) { require((c = a + b) >= b, "BoringMath: Add Overflow"); } function sub(uint64 a, uint64 b) internal pure returns (uint64 c) { require((c = a - b) <= a, "BoringMath: Underflow"); } } /// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint32. library BoringMath32 { function add(uint32 a, uint32 b) internal pure returns (uint32 c) { require((c = a + b) >= b, "BoringMath: Add Overflow"); } function sub(uint32 a, uint32 b) internal pure returns (uint32 c) { require((c = a - b) <= a, "BoringMath: Underflow"); } function mul(uint32 a, uint32 b) internal pure returns (uint32 c) { require(b == 0 || (c = a * b) / b == a, "BoringMath: Mul Overflow"); } function div(uint32 a, uint32 b) internal pure returns (uint32) { require(b > 0, "BoringMath: division by zero"); return a / b; } } /// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint112. library BoringMath112 { function add(uint112 a, uint112 b) internal pure returns (uint112 c) { require((c = a + b) >= b, "BoringMath: Add Overflow"); } function sub(uint112 a, uint112 b) internal pure returns (uint112 c) { require((c = a - b) <= a, "BoringMath: Underflow"); } function mul(uint112 a, uint112 b) internal pure returns (uint112 c) { require(b == 0 || (c = a * b) / b == a, "BoringMath: Mul Overflow"); } function div(uint112 a, uint112 b) internal pure returns (uint112) { require(b > 0, "BoringMath: division by zero"); return a / b; } } /// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint224. library BoringMath224 { function add(uint224 a, uint224 b) internal pure returns (uint224 c) { require((c = a + b) >= b, "BoringMath: Add Overflow"); } function sub(uint224 a, uint224 b) internal pure returns (uint224 c) { require((c = a - b) <= a, "BoringMath: Underflow"); } function mul(uint224 a, uint224 b) internal pure returns (uint224 c) { require(b == 0 || (c = a * b) / b == a, "BoringMath: Mul Overflow"); } function div(uint224 a, uint224 b) internal pure returns (uint224) { require(b > 0, "BoringMath: division by zero"); return a / b; } } // File: @openzeppelin\contracts\token\ERC20\IERC20.sol pragma solidity >=0.6.0 <0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ 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); } // File: @openzeppelin\contracts\math\SafeMath.sol pragma solidity >=0.6.0 <0.8.0; /** * @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, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a % b); } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { 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) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { 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, reverting 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) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a % b; } } // File: @openzeppelin\contracts\utils\Address.sol pragma solidity >=0.6.2 <0.8.0; /** * @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) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @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]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File: @openzeppelin\contracts\token\ERC20\SafeERC20.sol pragma solidity >=0.6.0 <0.8.0; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ 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)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ 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. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "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"); } } } // File: @openzeppelin\contracts\math\Math.sol pragma solidity >=0.6.0 <0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow, so we distribute return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2); } } // File: @openzeppelin\contracts\utils\Context.sol pragma solidity >=0.6.0 <0.8.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } } // File: @openzeppelin\contracts\access\Ownable.sol pragma solidity >=0.6.0 <0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor () internal { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } } // File: @openzeppelin\contracts\utils\ReentrancyGuard.sol pragma solidity >=0.6.0 <0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being 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 percentage 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. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor () internal { _status = _NOT_ENTERED; } /** * @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(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } } // File: contracts\CvxLockerV2.sol pragma solidity 0.6.12; pragma experimental ABIEncoderV2; /* CVX Locking contract for https://www.convexfinance.com/ CVX locked in this contract will be entitled to voting rights for the Convex Finance platform Based on EPS Staking contract for http://ellipsis.finance/ Based on SNX MultiRewards by iamdefinitelyahuman - https://github.com/iamdefinitelyahuman/multi-rewards V2: - change locking mechanism to lock to a future epoch instead of current - pending lock getter - relocking allocates weight to the current epoch instead of future, thus allows keeping voting weight in the same epoch a lock expires by relocking before a vote begins - balanceAtEpoch and supplyAtEpoch return proper values for future epochs - do not allow relocking directly to a new address */ contract CvxLockerV2 is ReentrancyGuard, Ownable { using BoringMath for uint256; using BoringMath224 for uint224; using BoringMath112 for uint112; using BoringMath32 for uint32; using SafeERC20 for IERC20; /* ========== STATE VARIABLES ========== */ struct Reward { bool useBoost; uint40 periodFinish; uint208 rewardRate; uint40 lastUpdateTime; uint208 rewardPerTokenStored; } struct Balances { uint112 locked; uint112 boosted; uint32 nextUnlockIndex; } struct LockedBalance { uint112 amount; uint112 boosted; uint32 unlockTime; } struct EarnedData { address token; uint256 amount; } struct Epoch { uint224 supply; //epoch boosted supply uint32 date; //epoch start date } //token constants IERC20 public constant stakingToken = IERC20(0x4e3FBD56CD56c3e72c1403e103b45Db9da5B9D2B); //cvx address public constant cvxCrv = address(0x62B9c7356A2Dc64a1969e19C23e4f579F9810Aa7); //rewards address[] public rewardTokens; mapping(address => Reward) public rewardData; // Duration that rewards are streamed over uint256 public constant rewardsDuration = 86400 * 7; // Duration of lock/earned penalty period uint256 public constant lockDuration = rewardsDuration * 16; // reward token -> distributor -> is approved to add rewards mapping(address => mapping(address => bool)) public rewardDistributors; // user -> reward token -> amount mapping(address => mapping(address => uint256)) public userRewardPerTokenPaid; mapping(address => mapping(address => uint256)) public rewards; //supplies and epochs uint256 public lockedSupply; uint256 public boostedSupply; Epoch[] public epochs; //mappings for balance data mapping(address => Balances) public balances; mapping(address => LockedBalance[]) public userLocks; //boost address public boostPayment = address(0x1389388d01708118b497f59521f6943Be2541bb7); uint256 public maximumBoostPayment = 0; uint256 public boostRate = 10000; uint256 public nextMaximumBoostPayment = 0; uint256 public nextBoostRate = 10000; uint256 public constant denominator = 10000; //staking uint256 public minimumStake = 10000; uint256 public maximumStake = 10000; address public stakingProxy; address public constant cvxcrvStaking = address(0x3Fe65692bfCD0e6CF84cB1E7d24108E434A7587e); uint256 public constant stakeOffsetOnLock = 500; //allow broader range for staking when depositing //management uint256 public kickRewardPerEpoch = 100; uint256 public kickRewardEpochDelay = 4; //shutdown bool public isShutdown = false; //erc20-like interface string private _name; string private _symbol; uint8 private immutable _decimals; /* ========== CONSTRUCTOR ========== */ constructor() public Ownable() { _name = "Vote Locked Convex Token"; _symbol = "vlCVX"; _decimals = 18; uint256 currentEpoch = block.timestamp.div(rewardsDuration).mul(rewardsDuration); epochs.push(Epoch({ supply: 0, date: uint32(currentEpoch) })); } function decimals() public view returns (uint8) { return _decimals; } function name() public view returns (string memory) { return _name; } function symbol() public view returns (string memory) { return _symbol; } function version() public view returns(uint256){ return 2; } /* ========== ADMIN CONFIGURATION ========== */ // Add a new reward token to be distributed to stakers function addReward( address _rewardsToken, address _distributor, bool _useBoost ) public onlyOwner { require(rewardData[_rewardsToken].lastUpdateTime == 0); require(_rewardsToken != address(stakingToken)); rewardTokens.push(_rewardsToken); rewardData[_rewardsToken].lastUpdateTime = uint40(block.timestamp); rewardData[_rewardsToken].periodFinish = uint40(block.timestamp); rewardData[_rewardsToken].useBoost = _useBoost; rewardDistributors[_rewardsToken][_distributor] = true; } // Modify approval for an address to call notifyRewardAmount function approveRewardDistributor( address _rewardsToken, address _distributor, bool _approved ) external onlyOwner { require(rewardData[_rewardsToken].lastUpdateTime > 0); rewardDistributors[_rewardsToken][_distributor] = _approved; } //Set the staking contract for the underlying cvx function setStakingContract(address _staking) external onlyOwner { require(stakingProxy == address(0), "!assign"); stakingProxy = _staking; } //set staking limits. will stake the mean of the two once either ratio is crossed function setStakeLimits(uint256 _minimum, uint256 _maximum) external onlyOwner { require(_minimum <= denominator, "min range"); require(_maximum <= denominator, "max range"); require(_minimum <= _maximum, "min range"); minimumStake = _minimum; maximumStake = _maximum; updateStakeRatio(0); } //set boost parameters function setBoost(uint256 _max, uint256 _rate, address _receivingAddress) external onlyOwner { require(_max < 1500, "over max payment"); //max 15% require(_rate < 30000, "over max rate"); //max 3x require(_receivingAddress != address(0), "invalid address"); //must point somewhere valid nextMaximumBoostPayment = _max; nextBoostRate = _rate; boostPayment = _receivingAddress; } //set kick incentive function setKickIncentive(uint256 _rate, uint256 _delay) external onlyOwner { require(_rate <= 500, "over max rate"); //max 5% per epoch require(_delay >= 2, "min delay"); //minimum 2 epochs of grace kickRewardPerEpoch = _rate; kickRewardEpochDelay = _delay; } //shutdown the contract. unstake all tokens. release all locks function shutdown() external onlyOwner { if (stakingProxy != address(0)) { uint256 stakeBalance = IStakingProxy(stakingProxy).getBalance(); IStakingProxy(stakingProxy).withdraw(stakeBalance); } isShutdown = true; } //set approvals for staking cvx and cvxcrv function setApprovals() external { IERC20(cvxCrv).safeApprove(cvxcrvStaking, 0); IERC20(cvxCrv).safeApprove(cvxcrvStaking, uint256(-1)); IERC20(stakingToken).safeApprove(stakingProxy, 0); IERC20(stakingToken).safeApprove(stakingProxy, uint256(-1)); } /* ========== VIEWS ========== */ function _rewardPerToken(address _rewardsToken) internal view returns(uint256) { if (boostedSupply == 0) { return rewardData[_rewardsToken].rewardPerTokenStored; } return uint256(rewardData[_rewardsToken].rewardPerTokenStored).add( _lastTimeRewardApplicable(rewardData[_rewardsToken].periodFinish).sub( rewardData[_rewardsToken].lastUpdateTime).mul( rewardData[_rewardsToken].rewardRate).mul(1e18).div(rewardData[_rewardsToken].useBoost ? boostedSupply : lockedSupply) ); } function _earned( address _user, address _rewardsToken, uint256 _balance ) internal view returns(uint256) { return _balance.mul( _rewardPerToken(_rewardsToken).sub(userRewardPerTokenPaid[_user][_rewardsToken]) ).div(1e18).add(rewards[_user][_rewardsToken]); } function _lastTimeRewardApplicable(uint256 _finishTime) internal view returns(uint256){ return Math.min(block.timestamp, _finishTime); } function lastTimeRewardApplicable(address _rewardsToken) public view returns(uint256) { return _lastTimeRewardApplicable(rewardData[_rewardsToken].periodFinish); } function rewardPerToken(address _rewardsToken) external view returns(uint256) { return _rewardPerToken(_rewardsToken); } function getRewardForDuration(address _rewardsToken) external view returns(uint256) { return uint256(rewardData[_rewardsToken].rewardRate).mul(rewardsDuration); } // Address and claimable amount of all reward tokens for the given account function claimableRewards(address _account) external view returns(EarnedData[] memory userRewards) { userRewards = new EarnedData[](rewardTokens.length); Balances storage userBalance = balances[_account]; uint256 boostedBal = userBalance.boosted; for (uint256 i = 0; i < userRewards.length; i++) { address token = rewardTokens[i]; userRewards[i].token = token; userRewards[i].amount = _earned(_account, token, rewardData[token].useBoost ? boostedBal : userBalance.locked); } return userRewards; } // Total BOOSTED balance of an account, including unlocked but not withdrawn tokens function rewardWeightOf(address _user) view external returns(uint256 amount) { return balances[_user].boosted; } // total token balance of an account, including unlocked but not withdrawn tokens function lockedBalanceOf(address _user) view external returns(uint256 amount) { return balances[_user].locked; } //BOOSTED balance of an account which only includes properly locked tokens as of the most recent eligible epoch function balanceOf(address _user) view external returns(uint256 amount) { LockedBalance[] storage locks = userLocks[_user]; Balances storage userBalance = balances[_user]; uint256 nextUnlockIndex = userBalance.nextUnlockIndex; //start with current boosted amount amount = balances[_user].boosted; uint256 locksLength = locks.length; //remove old records only (will be better gas-wise than adding up) for (uint i = nextUnlockIndex; i < locksLength; i++) { if (locks[i].unlockTime <= block.timestamp) { amount = amount.sub(locks[i].boosted); } else { //stop now as no futher checks are needed break; } } //also remove amount locked in the next epoch uint256 currentEpoch = block.timestamp.div(rewardsDuration).mul(rewardsDuration); if (locksLength > 0 && uint256(locks[locksLength - 1].unlockTime).sub(lockDuration) > currentEpoch) { amount = amount.sub(locks[locksLength - 1].boosted); } return amount; } //BOOSTED balance of an account which only includes properly locked tokens at the given epoch function balanceAtEpochOf(uint256 _epoch, address _user) view external returns(uint256 amount) { LockedBalance[] storage locks = userLocks[_user]; //get timestamp of given epoch index uint256 epochTime = epochs[_epoch].date; //get timestamp of first non-inclusive epoch uint256 cutoffEpoch = epochTime.sub(lockDuration); //need to add up since the range could be in the middle somewhere //traverse inversely to make more current queries more gas efficient for (uint i = locks.length - 1; i + 1 != 0; i--) { uint256 lockEpoch = uint256(locks[i].unlockTime).sub(lockDuration); //lock epoch must be less or equal to the epoch we're basing from. if (lockEpoch <= epochTime) { if (lockEpoch > cutoffEpoch) { amount = amount.add(locks[i].boosted); } else { //stop now as no futher checks matter break; } } } return amount; } //return currently locked but not active balance function pendingLockOf(address _user) view external returns(uint256 amount) { LockedBalance[] storage locks = userLocks[_user]; uint256 locksLength = locks.length; //return amount if latest lock is in the future uint256 currentEpoch = block.timestamp.div(rewardsDuration).mul(rewardsDuration); if (locksLength > 0 && uint256(locks[locksLength - 1].unlockTime).sub(lockDuration) > currentEpoch) { return locks[locksLength - 1].boosted; } return 0; } function pendingLockAtEpochOf(uint256 _epoch, address _user) view external returns(uint256 amount) { LockedBalance[] storage locks = userLocks[_user]; //get next epoch from the given epoch index uint256 nextEpoch = uint256(epochs[_epoch].date).add(rewardsDuration); //traverse inversely to make more current queries more gas efficient for (uint i = locks.length - 1; i + 1 != 0; i--) { uint256 lockEpoch = uint256(locks[i].unlockTime).sub(lockDuration); //return the next epoch balance if (lockEpoch == nextEpoch) { return locks[i].boosted; }else if(lockEpoch < nextEpoch){ //no need to check anymore break; } } return 0; } //supply of all properly locked BOOSTED balances at most recent eligible epoch function totalSupply() view external returns(uint256 supply) { uint256 currentEpoch = block.timestamp.div(rewardsDuration).mul(rewardsDuration); uint256 cutoffEpoch = currentEpoch.sub(lockDuration); uint256 epochindex = epochs.length; //do not include next epoch's supply if ( uint256(epochs[epochindex - 1].date) > currentEpoch ) { epochindex--; } //traverse inversely to make more current queries more gas efficient for (uint i = epochindex - 1; i + 1 != 0; i--) { Epoch storage e = epochs[i]; if (uint256(e.date) <= cutoffEpoch) { break; } supply = supply.add(e.supply); } return supply; } //supply of all properly locked BOOSTED balances at the given epoch function totalSupplyAtEpoch(uint256 _epoch) view external returns(uint256 supply) { uint256 epochStart = uint256(epochs[_epoch].date).div(rewardsDuration).mul(rewardsDuration); uint256 cutoffEpoch = epochStart.sub(lockDuration); //traverse inversely to make more current queries more gas efficient for (uint i = _epoch; i + 1 != 0; i--) { Epoch storage e = epochs[i]; if (uint256(e.date) <= cutoffEpoch) { break; } supply = supply.add(epochs[i].supply); } return supply; } //find an epoch index based on timestamp function findEpochId(uint256 _time) view external returns(uint256 epoch) { uint256 max = epochs.length - 1; uint256 min = 0; //convert to start point _time = _time.div(rewardsDuration).mul(rewardsDuration); for (uint256 i = 0; i < 128; i++) { if (min >= max) break; uint256 mid = (min + max + 1) / 2; uint256 midEpochBlock = epochs[mid].date; if(midEpochBlock == _time){ //found return mid; }else if (midEpochBlock < _time) { min = mid; } else{ max = mid - 1; } } return min; } // Information on a user's locked balances function lockedBalances( address _user ) view external returns( uint256 total, uint256 unlockable, uint256 locked, LockedBalance[] memory lockData ) { LockedBalance[] storage locks = userLocks[_user]; Balances storage userBalance = balances[_user]; uint256 nextUnlockIndex = userBalance.nextUnlockIndex; uint256 idx; for (uint i = nextUnlockIndex; i < locks.length; i++) { if (locks[i].unlockTime > block.timestamp) { if (idx == 0) { lockData = new LockedBalance[](locks.length - i); } lockData[idx] = locks[i]; idx++; locked = locked.add(locks[i].amount); } else { unlockable = unlockable.add(locks[i].amount); } } return (userBalance.locked, unlockable, locked, lockData); } //number of epochs function epochCount() external view returns(uint256) { return epochs.length; } /* ========== MUTATIVE FUNCTIONS ========== */ function checkpointEpoch() external { _checkpointEpoch(); } //insert a new epoch if needed. fill in any gaps function _checkpointEpoch() internal { //create new epoch in the future where new non-active locks will lock to uint256 nextEpoch = block.timestamp.div(rewardsDuration).mul(rewardsDuration).add(rewardsDuration); uint256 epochindex = epochs.length; //first epoch add in constructor, no need to check 0 length //check to add if (epochs[epochindex - 1].date < nextEpoch) { //fill any epoch gaps while(epochs[epochs.length-1].date != nextEpoch){ uint256 nextEpochDate = uint256(epochs[epochs.length-1].date).add(rewardsDuration); epochs.push(Epoch({ supply: 0, date: uint32(nextEpochDate) })); } //update boost parameters on a new epoch if(boostRate != nextBoostRate){ boostRate = nextBoostRate; } if(maximumBoostPayment != nextMaximumBoostPayment){ maximumBoostPayment = nextMaximumBoostPayment; } } } // Locked tokens cannot be withdrawn for lockDuration and are eligible to receive stakingReward rewards function lock(address _account, uint256 _amount, uint256 _spendRatio) external nonReentrant updateReward(_account) { //pull tokens stakingToken.safeTransferFrom(msg.sender, address(this), _amount); //lock _lock(_account, _amount, _spendRatio, false); } //lock tokens function _lock(address _account, uint256 _amount, uint256 _spendRatio, bool _isRelock) internal { require(_amount > 0, "Cannot stake 0"); require(_spendRatio <= maximumBoostPayment, "over max spend"); require(!isShutdown, "shutdown"); Balances storage bal = balances[_account]; //must try check pointing epoch first _checkpointEpoch(); //calc lock and boosted amount uint256 spendAmount = _amount.mul(_spendRatio).div(denominator); uint256 boostRatio = boostRate.mul(_spendRatio).div(maximumBoostPayment==0?1:maximumBoostPayment); uint112 lockAmount = _amount.sub(spendAmount).to112(); uint112 boostedAmount = _amount.add(_amount.mul(boostRatio).div(denominator)).to112(); //add user balances bal.locked = bal.locked.add(lockAmount); bal.boosted = bal.boosted.add(boostedAmount); //add to total supplies lockedSupply = lockedSupply.add(lockAmount); boostedSupply = boostedSupply.add(boostedAmount); //add user lock records or add to current uint256 lockEpoch = block.timestamp.div(rewardsDuration).mul(rewardsDuration); //if a fresh lock, add on an extra duration period if(!_isRelock){ lockEpoch = lockEpoch.add(rewardsDuration); } uint256 unlockTime = lockEpoch.add(lockDuration); uint256 idx = userLocks[_account].length; //if the latest user lock is smaller than this lock, always just add new entry to the end of the list if (idx == 0 || userLocks[_account][idx - 1].unlockTime < unlockTime) { userLocks[_account].push(LockedBalance({ amount: lockAmount, boosted: boostedAmount, unlockTime: uint32(unlockTime) })); } else { //else add to a current lock //if latest lock is further in the future, lower index //this can only happen if relocking an expired lock after creating a new lock if(userLocks[_account][idx - 1].unlockTime > unlockTime){ idx--; } //if idx points to the epoch when same unlock time, update //(this is always true with a normal lock but maybe not with relock) if(userLocks[_account][idx - 1].unlockTime == unlockTime){ LockedBalance storage userL = userLocks[_account][idx - 1]; userL.amount = userL.amount.add(lockAmount); userL.boosted = userL.boosted.add(boostedAmount); }else{ //can only enter here if a relock is made after a lock and there's no lock entry //for the current epoch. //ex a list of locks such as "[...][older][current*][next]" but without a "current" lock //length - 1 is the next epoch //length - 2 is a past epoch //thus need to insert an entry for current epoch at the 2nd to last entry //we will copy and insert the tail entry(next) and then overwrite length-2 entry //reset idx idx = userLocks[_account].length; //get current last item LockedBalance storage userL = userLocks[_account][idx - 1]; //add a copy to end of list userLocks[_account].push(LockedBalance({ amount: userL.amount, boosted: userL.boosted, unlockTime: userL.unlockTime })); //insert current epoch lock entry by overwriting the entry at length-2 userL.amount = lockAmount; userL.boosted = boostedAmount; userL.unlockTime = uint32(unlockTime); } } //update epoch supply, epoch checkpointed above so safe to add to latest uint256 eIndex = epochs.length - 1; //if relock, epoch should be current and not next, thus need to decrease index to length-2 if(_isRelock){ eIndex--; } Epoch storage e = epochs[eIndex]; e.supply = e.supply.add(uint224(boostedAmount)); //send boost payment if (spendAmount > 0) { stakingToken.safeTransfer(boostPayment, spendAmount); } //update staking, allow a bit of leeway for smaller deposits to reduce gas updateStakeRatio(stakeOffsetOnLock); emit Staked(_account, lockEpoch, _amount, lockAmount, boostedAmount); } // Withdraw all currently locked tokens where the unlock time has passed function _processExpiredLocks(address _account, bool _relock, uint256 _spendRatio, address _withdrawTo, address _rewardAddress, uint256 _checkDelay) internal updateReward(_account) { LockedBalance[] storage locks = userLocks[_account]; Balances storage userBalance = balances[_account]; uint112 locked; uint112 boostedAmount; uint256 length = locks.length; uint256 reward = 0; if (isShutdown || locks[length - 1].unlockTime <= block.timestamp.sub(_checkDelay)) { //if time is beyond last lock, can just bundle everything together locked = userBalance.locked; boostedAmount = userBalance.boosted; //dont delete, just set next index userBalance.nextUnlockIndex = length.to32(); //check for kick reward //this wont have the exact reward rate that you would get if looped through //but this section is supposed to be for quick and easy low gas processing of all locks //we'll assume that if the reward was good enough someone would have processed at an earlier epoch if (_checkDelay > 0) { uint256 currentEpoch = block.timestamp.sub(_checkDelay).div(rewardsDuration).mul(rewardsDuration); uint256 epochsover = currentEpoch.sub(uint256(locks[length - 1].unlockTime)).div(rewardsDuration); uint256 rRate = MathUtil.min(kickRewardPerEpoch.mul(epochsover+1), denominator); reward = uint256(locks[length - 1].amount).mul(rRate).div(denominator); } } else { //use a processed index(nextUnlockIndex) to not loop as much //deleting does not change array length uint32 nextUnlockIndex = userBalance.nextUnlockIndex; for (uint i = nextUnlockIndex; i < length; i++) { //unlock time must be less or equal to time if (locks[i].unlockTime > block.timestamp.sub(_checkDelay)) break; //add to cumulative amounts locked = locked.add(locks[i].amount); boostedAmount = boostedAmount.add(locks[i].boosted); //check for kick reward //each epoch over due increases reward if (_checkDelay > 0) { uint256 currentEpoch = block.timestamp.sub(_checkDelay).div(rewardsDuration).mul(rewardsDuration); uint256 epochsover = currentEpoch.sub(uint256(locks[i].unlockTime)).div(rewardsDuration); uint256 rRate = MathUtil.min(kickRewardPerEpoch.mul(epochsover+1), denominator); reward = reward.add( uint256(locks[i].amount).mul(rRate).div(denominator)); } //set next unlock index nextUnlockIndex++; } //update next unlock index userBalance.nextUnlockIndex = nextUnlockIndex; } require(locked > 0, "no exp locks"); //update user balances and total supplies userBalance.locked = userBalance.locked.sub(locked); userBalance.boosted = userBalance.boosted.sub(boostedAmount); lockedSupply = lockedSupply.sub(locked); boostedSupply = boostedSupply.sub(boostedAmount); emit Withdrawn(_account, locked, _relock); //send process incentive if (reward > 0) { //if theres a reward(kicked), it will always be a withdraw only //preallocate enough cvx from stake contract to pay for both reward and withdraw allocateCVXForTransfer(uint256(locked)); //reduce return amount by the kick reward locked = locked.sub(reward.to112()); //transfer reward transferCVX(_rewardAddress, reward, false); emit KickReward(_rewardAddress, _account, reward); }else if(_spendRatio > 0){ //preallocate enough cvx to transfer the boost cost allocateCVXForTransfer( uint256(locked).mul(_spendRatio).div(denominator) ); } //relock or return to user if (_relock) { _lock(_withdrawTo, locked, _spendRatio, true); } else { transferCVX(_withdrawTo, locked, true); } } // withdraw expired locks to a different address function withdrawExpiredLocksTo(address _withdrawTo) external nonReentrant { _processExpiredLocks(msg.sender, false, 0, _withdrawTo, msg.sender, 0); } // Withdraw/relock all currently locked tokens where the unlock time has passed function processExpiredLocks(bool _relock) external nonReentrant { _processExpiredLocks(msg.sender, _relock, 0, msg.sender, msg.sender, 0); } function kickExpiredLocks(address _account) external nonReentrant { //allow kick after grace period of 'kickRewardEpochDelay' _processExpiredLocks(_account, false, 0, _account, msg.sender, rewardsDuration.mul(kickRewardEpochDelay)); } //pull required amount of cvx from staking for an upcoming transfer function allocateCVXForTransfer(uint256 _amount) internal{ uint256 balance = stakingToken.balanceOf(address(this)); if (_amount > balance) { IStakingProxy(stakingProxy).withdraw(_amount.sub(balance)); } } //transfer helper: pull enough from staking, transfer, updating staking ratio function transferCVX(address _account, uint256 _amount, bool _updateStake) internal { //allocate enough cvx from staking for the transfer allocateCVXForTransfer(_amount); //transfer stakingToken.safeTransfer(_account, _amount); //update staking if(_updateStake){ updateStakeRatio(0); } } //calculate how much cvx should be staked. update if needed function updateStakeRatio(uint256 _offset) internal { if (isShutdown) return; //get balances uint256 local = stakingToken.balanceOf(address(this)); uint256 staked = IStakingProxy(stakingProxy).getBalance(); uint256 total = local.add(staked); if(total == 0) return; //current staked ratio uint256 ratio = staked.mul(denominator).div(total); //mean will be where we reset to if unbalanced uint256 mean = maximumStake.add(minimumStake).div(2); uint256 max = maximumStake.add(_offset); uint256 min = Math.min(minimumStake, minimumStake - _offset); if (ratio > max) { //remove uint256 remove = staked.sub(total.mul(mean).div(denominator)); IStakingProxy(stakingProxy).withdraw(remove); } else if (ratio < min) { //add uint256 increase = total.mul(mean).div(denominator).sub(staked); stakingToken.safeTransfer(stakingProxy, increase); IStakingProxy(stakingProxy).stake(); } } // Claim all pending rewards function getReward(address _account, bool _stake) public nonReentrant updateReward(_account) { for (uint i; i < rewardTokens.length; i++) { address _rewardsToken = rewardTokens[i]; uint256 reward = rewards[_account][_rewardsToken]; if (reward > 0) { rewards[_account][_rewardsToken] = 0; if (_rewardsToken == cvxCrv && _stake) { IRewardStaking(cvxcrvStaking).stakeFor(_account, reward); } else { IERC20(_rewardsToken).safeTransfer(_account, reward); } emit RewardPaid(_account, _rewardsToken, reward); } } } // claim all pending rewards function getReward(address _account) external{ getReward(_account,false); } /* ========== RESTRICTED FUNCTIONS ========== */ function _notifyReward(address _rewardsToken, uint256 _reward) internal { Reward storage rdata = rewardData[_rewardsToken]; if (block.timestamp >= rdata.periodFinish) { rdata.rewardRate = _reward.div(rewardsDuration).to208(); } else { uint256 remaining = uint256(rdata.periodFinish).sub(block.timestamp); uint256 leftover = remaining.mul(rdata.rewardRate); rdata.rewardRate = _reward.add(leftover).div(rewardsDuration).to208(); } rdata.lastUpdateTime = block.timestamp.to40(); rdata.periodFinish = block.timestamp.add(rewardsDuration).to40(); } function notifyRewardAmount(address _rewardsToken, uint256 _reward) external updateReward(address(0)) { require(rewardDistributors[_rewardsToken][msg.sender]); require(_reward > 0, "No reward"); _notifyReward(_rewardsToken, _reward); // handle the transfer of reward tokens via `transferFrom` to reduce the number // of transactions required and ensure correctness of the _reward amount IERC20(_rewardsToken).safeTransferFrom(msg.sender, address(this), _reward); emit RewardAdded(_rewardsToken, _reward); if(_rewardsToken == cvxCrv){ //update staking ratio if main reward updateStakeRatio(0); } } // Added to support recovering LP Rewards from other systems such as BAL to be distributed to holders function recoverERC20(address _tokenAddress, uint256 _tokenAmount) external onlyOwner { require(_tokenAddress != address(stakingToken), "Cannot withdraw staking token"); require(rewardData[_tokenAddress].lastUpdateTime == 0, "Cannot withdraw reward token"); IERC20(_tokenAddress).safeTransfer(owner(), _tokenAmount); emit Recovered(_tokenAddress, _tokenAmount); } /* ========== MODIFIERS ========== */ modifier updateReward(address _account) { {//stack too deep Balances storage userBalance = balances[_account]; uint256 boostedBal = userBalance.boosted; for (uint i = 0; i < rewardTokens.length; i++) { address token = rewardTokens[i]; rewardData[token].rewardPerTokenStored = _rewardPerToken(token).to208(); rewardData[token].lastUpdateTime = _lastTimeRewardApplicable(rewardData[token].periodFinish).to40(); if (_account != address(0)) { //check if reward is boostable or not. use boosted or locked balance accordingly rewards[_account][token] = _earned(_account, token, rewardData[token].useBoost ? boostedBal : userBalance.locked ); userRewardPerTokenPaid[_account][token] = rewardData[token].rewardPerTokenStored; } } } _; } /* ========== EVENTS ========== */ event RewardAdded(address indexed _token, uint256 _reward); event Staked(address indexed _user, uint256 indexed _epoch, uint256 _paidAmount, uint256 _lockedAmount, uint256 _boostedAmount); event Withdrawn(address indexed _user, uint256 _amount, bool _relocked); event KickReward(address indexed _user, address indexed _kicked, uint256 _reward); event RewardPaid(address indexed _user, address indexed _rewardsToken, uint256 _reward); event Recovered(address _token, uint256 _amount); }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_user","type":"address"},{"indexed":true,"internalType":"address","name":"_kicked","type":"address"},{"indexed":false,"internalType":"uint256","name":"_reward","type":"uint256"}],"name":"KickReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"Recovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"uint256","name":"_reward","type":"uint256"}],"name":"RewardAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_user","type":"address"},{"indexed":true,"internalType":"address","name":"_rewardsToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"_reward","type":"uint256"}],"name":"RewardPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_user","type":"address"},{"indexed":true,"internalType":"uint256","name":"_epoch","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_paidAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_lockedAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_boostedAmount","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_user","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"bool","name":"_relocked","type":"bool"}],"name":"Withdrawn","type":"event"},{"inputs":[{"internalType":"address","name":"_rewardsToken","type":"address"},{"internalType":"address","name":"_distributor","type":"address"},{"internalType":"bool","name":"_useBoost","type":"bool"}],"name":"addReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardsToken","type":"address"},{"internalType":"address","name":"_distributor","type":"address"},{"internalType":"bool","name":"_approved","type":"bool"}],"name":"approveRewardDistributor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_epoch","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"balanceAtEpochOf","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balances","outputs":[{"internalType":"uint112","name":"locked","type":"uint112"},{"internalType":"uint112","name":"boosted","type":"uint112"},{"internalType":"uint32","name":"nextUnlockIndex","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"boostPayment","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"boostRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"boostedSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"checkpointEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"claimableRewards","outputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct CvxLockerV2.EarnedData[]","name":"userRewards","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cvxCrv","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cvxcrvStaking","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"denominator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"epochCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"epochs","outputs":[{"internalType":"uint224","name":"supply","type":"uint224"},{"internalType":"uint32","name":"date","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_time","type":"uint256"}],"name":"findEpochId","outputs":[{"internalType":"uint256","name":"epoch","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"bool","name":"_stake","type":"bool"}],"name":"getReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardsToken","type":"address"}],"name":"getRewardForDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isShutdown","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"kickExpiredLocks","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"kickRewardEpochDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"kickRewardPerEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardsToken","type":"address"}],"name":"lastTimeRewardApplicable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_spendRatio","type":"uint256"}],"name":"lock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lockDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"lockedBalanceOf","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"lockedBalances","outputs":[{"internalType":"uint256","name":"total","type":"uint256"},{"internalType":"uint256","name":"unlockable","type":"uint256"},{"internalType":"uint256","name":"locked","type":"uint256"},{"components":[{"internalType":"uint112","name":"amount","type":"uint112"},{"internalType":"uint112","name":"boosted","type":"uint112"},{"internalType":"uint32","name":"unlockTime","type":"uint32"}],"internalType":"struct CvxLockerV2.LockedBalance[]","name":"lockData","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockedSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maximumBoostPayment","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maximumStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minimumStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextBoostRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextMaximumBoostPayment","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardsToken","type":"address"},{"internalType":"uint256","name":"_reward","type":"uint256"}],"name":"notifyRewardAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_epoch","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"pendingLockAtEpochOf","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"pendingLockOf","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_relock","type":"bool"}],"name":"processExpiredLocks","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"},{"internalType":"uint256","name":"_tokenAmount","type":"uint256"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewardData","outputs":[{"internalType":"bool","name":"useBoost","type":"bool"},{"internalType":"uint40","name":"periodFinish","type":"uint40"},{"internalType":"uint208","name":"rewardRate","type":"uint208"},{"internalType":"uint40","name":"lastUpdateTime","type":"uint40"},{"internalType":"uint208","name":"rewardPerTokenStored","type":"uint208"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"rewardDistributors","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardsToken","type":"address"}],"name":"rewardPerToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"rewardWeightOf","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"rewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"setApprovals","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_max","type":"uint256"},{"internalType":"uint256","name":"_rate","type":"uint256"},{"internalType":"address","name":"_receivingAddress","type":"address"}],"name":"setBoost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rate","type":"uint256"},{"internalType":"uint256","name":"_delay","type":"uint256"}],"name":"setKickIncentive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minimum","type":"uint256"},{"internalType":"uint256","name":"_maximum","type":"uint256"}],"name":"setStakeLimits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_staking","type":"address"}],"name":"setStakingContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shutdown","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakeOffsetOnLock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakingProxy","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakingToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"supply","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_epoch","type":"uint256"}],"name":"totalSupplyAtEpoch","outputs":[{"internalType":"uint256","name":"supply","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"userLocks","outputs":[{"internalType":"uint112","name":"amount","type":"uint112"},{"internalType":"uint112","name":"boosted","type":"uint112"},{"internalType":"uint32","name":"unlockTime","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"userRewardPerTokenPaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_withdrawTo","type":"address"}],"name":"withdrawExpiredLocksTo","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60a0604052600c80546001600160a01b031916731389388d01708118b497f59521f6943be2541bb71790556000600d819055612710600e819055600f9190915560108190556011819055601255606460145560046015556016805460ff191690553480156200006d57600080fd5b50600160009081556200007f62000204565b600180546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506040805180820190915260188082527f566f7465204c6f636b656420436f6e76657820546f6b656e00000000000000006020909201918252620001139160179162000285565b50604080518082019091526005808252640ecd886acb60db1b6020909201918252620001429160189162000285565b50600960f91b60805260006200018162093a806200016d428262000208602090811b6200276c17901c565b6200024960201b6200279e1790919060201c565b60408051808201909152600080825263ffffffff9283166020830190815260098054600181018255925291517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af90910180549251909316600160e01b026001600160e01b039182166001600160e01b03199093169290921716179055506200038f565b3390565b6000808211620002355760405162461bcd60e51b81526004016200022c9062000321565b60405180910390fd5b8183816200023f57fe5b0490505b92915050565b600081158062000266575050808202828282816200026357fe5b04145b620002435760405162461bcd60e51b81526004016200022c9062000358565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620002c857805160ff1916838001178555620002f8565b82800160010185558215620002f8579182015b82811115620002f8578251825591602001919060010190620002db565b50620003069291506200030a565b5090565b5b808211156200030657600081556001016200030b565b6020808252601c908201527f426f72696e674d6174683a206469766973696f6e206279207a65726f00000000604082015260600190565b60208082526018908201527f426f72696e674d6174683a204d756c204f766572666c6f770000000000000000604082015260600190565b60805160f81c614c92620003ad60003980610d3b5250614c926000f3fe608060405234801561001057600080fd5b50600436106103f15760003560e01c8063887c7dc511610215578063bf86d69011610125578063dc01f60d116100b8578063ec5ffac211610087578063ec5ffac2146107e8578063f1229777146107f0578063f2fde38b14610803578063f826159714610816578063fc0e74d114610829576103f1565b8063dc01f60d1461079a578063e2ab691d146107ba578063e432488d146107cd578063e70b9e27146107d5576103f1565b8063ca5c7b91116100f4578063ca5c7b9114610759578063cb1b9a7414610761578063d36f12fb14610774578063d3c45c7614610787576103f1565b8063bf86d69014610715578063c00007b01461071d578063c1009f4b14610730578063c6b61e4c14610738576103f1565b8063a81653c9116101a8578063b187bc2211610177578063b187bc22146106d7578063b5c6b453146106df578063b5ed7a66146106e7578063b66503cf146106ef578063bcd1101414610702576103f1565b8063a81653c9146106a1578063a98e05bb146106b4578063aa33fedb146106bc578063ae8d4825146106cf576103f1565b806395d89b41116101e457806395d89b411461067657806396ce07951461067e5780639bdc7467146106865780639dd373b91461068e576103f1565b8063887c7dc5146106355780638980f11f146106485780638c9bd1b51461065b5780638da5cb5b1461066e576103f1565b8063638634ee1161031057806370b36d79116102a35780637bb7bed1116102725780637bb7bed1146106025780637bd48c7c1461061557806382480df91461061d578063829965cc146106255780638757b15b1461062d576103f1565b806370b36d79146105d7578063715018a6146105ea57806372f702f3146105f257806375aadf61146105fa576103f1565b806368edd2bb116102df57806368edd2bb1461058b5780637035ab981461059e5780637050ccd9146105b157806370a08231146105c4576103f1565b8063638634ee1461054a57806363f1c8e21461055d578063648bb8ad146105705780636724c91014610578576103f1565b80632fe871081161038857806339fc97131161035757806339fc9713146104eb57806348e5d9f81461050b57806354fd4d501461052f5780635935573614610537576103f1565b80632fe87108146104a6578063312ff839146104b9578063313ce567146104ce578063386a9525146104e3576103f1565b80631c607395116103c45780631c6073951461045457806322f80d111461046757806327e235e31461047c5780632e9564e41461049e576103f1565b806304554443146103f65780630483a7f61461041457806306fdde031461043757806318160ddd1461044c575b600080fd5b6103fe610831565b60405161040b9190614b55565b60405180910390f35b610427610422366004614233565b610838565b60405161040b9493929190614b7d565b61043f6109fe565b60405161040b9190614559565b6103fe610a94565b6103fe6104623660046143c8565b610b6a565b61046f610c73565b60405161040b9190614455565b61048f61048a366004614233565b610c82565b60405161040b93929190614b0d565b6103fe610cb8565b6103fe6104b4366004614233565b610cbe565b6104cc6104c7366004614360565b610ced565b005b6104d6610d39565b60405161040b9190614bff565b6103fe610d5d565b6104fe6104f936600461424e565b610d64565b60405161040b9190614518565b61051e610519366004614233565b610d84565b60405161040b959493929190614523565b6103fe610dd0565b6103fe610545366004614233565b610dd5565b6103fe610558366004614233565b610df9565b6104cc61056b3660046143eb565b610e27565b6103fe610eb4565b6104cc610586366004614282565b610eba565b6103fe610599366004614233565b610f5f565b6103fe6105ac36600461424e565b610ffa565b6104cc6105bf3660046142cc565b611017565b6103fe6105d2366004614233565b611384565b6103fe6105e5366004614398565b6114a8565b6104cc61157f565b61046f611608565b6103fe611620565b61046f610610366004614398565b611626565b6103fe61164d565b61046f611653565b6103fe61166b565b6104cc611671565b6104cc610643366004614233565b611737565b6104cc610656366004614303565b611788565b6104cc6106693660046143eb565b61189d565b61046f611958565b61043f611967565b6103fe6119c8565b6103fe6119ce565b6104cc61069c366004614233565b6119d4565b6104cc6106af36600461440c565b611a5e565b61046f611b2f565b61048f6106ca366004614303565b611b3e565b61046f611b8a565b6103fe611ba2565b6103fe611ba8565b6103fe611bae565b6104cc6106fd366004614303565b611bb4565b6103fe610710366004614233565b611e55565b6104fe611e8b565b6104cc61072b366004614233565b611e94565b6104cc611ea2565b61074b610746366004614398565b611eaa565b60405161040b929190614b36565b6103fe611edf565b6103fe61076f3660046143c8565b611ee5565b6104cc610782366004614233565b611fc7565b6104cc610795366004614282565b612002565b6107ad6107a8366004614233565b612151565b60405161040b91906144c0565b6104cc6107c836600461432d565b61228a565b6103fe61248d565b6103fe6107e336600461424e565b612493565b6103fe6124b0565b6103fe6107fe366004614233565b6124b6565b6104cc610811366004614233565b6124c1565b6103fe610824366004614398565b612582565b6104cc61262c565b6293a80081565b6001600160a01b0381166000908152600b60209081526040808320600a9092528220805483928392606092600160e01b900463ffffffff1684815b84548110156109e6574285828154811061088957fe5b600091825260209091200154600160e01b900463ffffffff1611156109b0578161090657845481900367ffffffffffffffff811180156108c857600080fd5b5060405190808252806020026020018201604052801561090257816020015b6108ef6141e5565b8152602001906001900390816108e75790505b5095505b84818154811061091257fe5b60009182526020918290206040805160608101825291909201546001600160701b038082168352600160701b8204169382019390935263ffffffff600160e01b9093049290921690820152865187908490811061096b57fe5b602002602001018190525081806001019250506109a985828154811061098d57fe5b60009182526020909120015488906001600160701b03166127d5565b96506109de565b6109db8582815481106109bf57fe5b60009182526020909120015489906001600160701b03166127d5565b97505b600101610873565b505090546001600160701b0316955050509193509193565b60178054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610a8a5780601f10610a5f57610100808354040283529160200191610a8a565b820191906000526020600020905b815481529060010190602001808311610a6d57829003601f168201915b5050505050905090565b600080610aae62093a80610aa8428261276c565b9061279e565b90506000610abf826293a8006127f8565b6009805491925083906000198301838110610ad657fe5b600091825260209091200154600160e01b900463ffffffff161115610afa57600019015b60001981015b6001810115610b6357600060098281548110610b1857fe5b60009182526020909120018054909150600160e01b900463ffffffff168410610b415750610b63565b8054610b579087906001600160e01b03166127d5565b95505060001901610b00565b5050505090565b6001600160a01b0381166000908152600b602052604081206009805483919086908110610b9357fe5b600091825260208220015463ffffffff600160e01b90910481169250610bc09083906293a800906127f816565b8354909150600019015b6001810115610c68576000610c0e62093a80601002868481548110610beb57fe5b60009182526020909120015463ffffffff600160e01b909104811691906127f816565b9050838111610c5e5782811115610c5857610c51858381548110610c2e57fe5b6000918252602090912001548790600160701b90046001600160701b03166127d5565b9550610c5e565b50610c68565b5060001901610bca565b505050505b92915050565b6013546001600160a01b031681565b600a602052600090815260409020546001600160701b0380821691600160701b810490911690600160e01b900463ffffffff1683565b600e5481565b6001600160a01b0381166000908152600a6020526040902054600160701b90046001600160701b03165b919050565b60026000541415610d195760405162461bcd60e51b8152600401610d10906149d4565b60405180910390fd5b6002600081905550610d31338260003333600061281b565b506001600055565b7f000000000000000000000000000000000000000000000000000000000000000090565b62093a8081565b600460209081526000928352604080842090915290825290205460ff1681565b6003602052600090815260409020805460019091015460ff82169164ffffffffff61010082048116926001600160d01b03600160301b90930483169291811691600160281b9091041685565b600290565b6001600160a01b03166000908152600a60205260409020546001600160701b031690565b6001600160a01b038116600090815260036020526040812054610c6d90610100900464ffffffffff16612eb4565b610e2f612ec0565b6001600160a01b0316610e40611958565b6001600160a01b031614610e665760405162461bcd60e51b8152600401610d1090614811565b6101f4821115610e885760405162461bcd60e51b8152600401610d10906146e9565b6002811015610ea95760405162461bcd60e51b8152600401610d109061487d565b601491909155601555565b6101f481565b610ec2612ec0565b6001600160a01b0316610ed3611958565b6001600160a01b031614610ef95760405162461bcd60e51b8152600401610d1090614811565b6001600160a01b03831660009081526003602052604090206001015464ffffffffff16610f2557600080fd5b6001600160a01b03928316600090815260046020908152604080832094909516825292909252919020805460ff1916911515919091179055565b6001600160a01b0381166000908152600b60205260408120805482610f8b62093a80610aa8428261276c565b9050600082118015610fb4575080610fb262093a80601002856001860381548110610beb57fe5b115b15610fef57826001830381548110610fc857fe5b600091825260209091200154600160701b90046001600160701b03169350610ce892505050565b506000949350505050565b600560209081526000928352604080842090915290825290205481565b6002600054141561103a5760405162461bcd60e51b8152600401610d10906149d4565b600260009081556001600160a01b0383168152600a6020526040812080548492600160701b9091046001600160701b0316905b6002548110156111f95760006002828154811061108657fe5b6000918252602090912001546001600160a01b031690506110ae6110a982612ec4565b612fcd565b6001600160a01b03821660009081526003602052604090206001810180546001600160d01b0393909316600160281b02600160281b600160f81b031990931692909217909155546111149061110f9064ffffffffff61010090910416612eb4565b612ffa565b6001600160a01b038281166000908152600360205260409020600101805464ffffffffff191664ffffffffff93909316929092179091558516156111f0576001600160a01b038116600090815260036020526040902054611191908690839060ff1661118a5786546001600160701b031661118c565b855b613021565b6001600160a01b0386811660008181526006602090815260408083209487168084529482528083209590955560038152848220600101549282526005815284822093825292909252919020600160281b9091046001600160d01b031690555b5060010161106d565b50505060005b6002548110156113795760006002828154811061121857fe5b60009182526020808320909101546001600160a01b03888116845260068352604080852091909216808552925290912054909150801561136f576001600160a01b038087166000908152600660209081526040808320938616808452939091528120557362b9c7356a2dc64a1969e19c23e4f579f9810aa714801561129a5750845b1561130f576040516305dc812160e31b8152733fe65692bfcd0e6cf84cb1e7d24108e434a7587e90632ee40908906112d890899085906004016144a7565b600060405180830381600087803b1580156112f257600080fd5b505af1158015611306573d6000803e3d6000fd5b50505050611323565b6113236001600160a01b0383168783613099565b816001600160a01b0316866001600160a01b03167f540798df468d7b23d11f156fdb954cb19ad414d150722a7b6d55ba369dea792e836040516113669190614b55565b60405180910390a35b50506001016111ff565b505060016000555050565b6001600160a01b0381166000908152600b60209081526040808320600a90925290912080548254600160701b82046001600160701b0316939291600160e01b900463ffffffff1690815b8181101561144757428582815481106113e357fe5b600091825260209091200154600160e01b900463ffffffff161161143a5761143385828154811061141057fe5b6000918252602090912001548790600160701b90046001600160701b03166127f8565b955061143f565b611447565b6001016113ce565b50600061145b62093a80610aa8428261276c565b905060008211801561148457508061148262093a80601002876001860381548110610beb57fe5b115b1561149e5761149b85600184038154811061141057fe5b95505b5050505050919050565b6000806114e962093a80610aa862093a80600987815481106114c657fe5b60009182526020909120015463ffffffff600160e01b9091048116919061276c16565b905060006114fa826293a8006127f8565b9050835b60018101156115775760006009828154811061151657fe5b60009182526020909120018054909150600160e01b900463ffffffff16831061153f5750611577565b61156b6009838154811061154f57fe5b60009182526020909120015486906001600160e01b03166127d5565b945050600019016114fe565b505050919050565b611587612ec0565b6001600160a01b0316611598611958565b6001600160a01b0316146115be5760405162461bcd60e51b8152600401610d1090614811565b6001546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600180546001600160a01b0319169055565b734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b81565b60085481565b6002818154811061163357fe5b6000918252602090912001546001600160a01b0316905081565b600f5481565b7362b9c7356a2dc64a1969e19c23e4f579f9810aa781565b60095490565b6116a57362b9c7356a2dc64a1969e19c23e4f579f9810aa7733fe65692bfcd0e6cf84cb1e7d24108e434a7587e60006130ef565b6116da7362b9c7356a2dc64a1969e19c23e4f579f9810aa7733fe65692bfcd0e6cf84cb1e7d24108e434a7587e6000196130ef565b60135461170790734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b906001600160a01b031660006130ef565b60135461173590734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b906001600160a01b03166000196130ef565b565b6002600054141561175a5760405162461bcd60e51b8152600401610d10906149d4565b6002600081905550610d3181600080843361178360155462093a8061279e90919063ffffffff16565b61281b565b611790612ec0565b6001600160a01b03166117a1611958565b6001600160a01b0316146117c75760405162461bcd60e51b8152600401610d1090614811565b6001600160a01b038216734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b14156118045760405162461bcd60e51b8152600401610d1090614846565b6001600160a01b03821660009081526003602052604090206001015464ffffffffff16156118445760405162461bcd60e51b8152600401610d109061499d565b61186061184f611958565b6001600160a01b0384169083613099565b7f8c1256b8896378cd5044f80c202f9772b9d77dc85c8a6eb51967210b09bfaa2882826040516118919291906144a7565b60405180910390a15050565b6118a5612ec0565b6001600160a01b03166118b6611958565b6001600160a01b0316146118dc5760405162461bcd60e51b8152600401610d1090614811565b6127108211156118fe5760405162461bcd60e51b8152600401610d10906148f9565b6127108111156119205760405162461bcd60e51b8152600401610d1090614a0b565b808211156119405760405162461bcd60e51b8152600401610d10906148f9565b6011829055601281905561195460006131b2565b5050565b6001546001600160a01b031690565b60188054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610a8a5780601f10610a5f57610100808354040283529160200191610a8a565b61271081565b60145481565b6119dc612ec0565b6001600160a01b03166119ed611958565b6001600160a01b031614611a135760405162461bcd60e51b8152600401610d1090614811565b6013546001600160a01b031615611a3c5760405162461bcd60e51b8152600401610d10906147f0565b601380546001600160a01b0319166001600160a01b0392909216919091179055565b611a66612ec0565b6001600160a01b0316611a77611958565b6001600160a01b031614611a9d5760405162461bcd60e51b8152600401610d1090614811565b6105dc8310611abe5760405162461bcd60e51b8152600401610d10906146bf565b6175308210611adf5760405162461bcd60e51b8152600401610d10906146e9565b6001600160a01b038116611b055760405162461bcd60e51b8152600401610d1090614736565b600f92909255601055600c80546001600160a01b0319166001600160a01b03909216919091179055565b600c546001600160a01b031681565b600b6020528160005260406000208181548110611b5757fe5b6000918252602090912001546001600160701b038082169350600160701b8204169150600160e01b900463ffffffff1683565b733fe65692bfcd0e6cf84cb1e7d24108e434a7587e81565b600d5481565b60125481565b60105481565b6000808052600a6020527f13da86008ba1c6922daee3e07db95305ef49ebced9f5467a0b8613fcc6b343e38054600160701b90046001600160701b0316825b600254811015611d6e57600060028281548110611c0c57fe5b6000918252602090912001546001600160a01b03169050611c2f6110a982612ec4565b6001600160a01b03821660009081526003602052604090206001810180546001600160d01b0393909316600160281b02600160281b600160f81b03199093169290921790915554611c909061110f9064ffffffffff61010090910416612eb4565b6001600160a01b038281166000908152600360205260409020600101805464ffffffffff191664ffffffffff9390931692909217909155851615611d65576001600160a01b038116600090815260036020526040902054611d06908690839060ff1661118a5786546001600160701b031661118c565b6001600160a01b0386811660008181526006602090815260408083209487168084529482528083209590955560038152848220600101549282526005815284822093825292909252919020600160281b9091046001600160d01b031690555b50600101611bf3565b5050506001600160a01b038316600090815260046020908152604080832033845290915290205460ff16611da157600080fd5b60008211611dc15760405162461bcd60e51b8152600401610d10906147cd565b611dcb838361349c565b611de06001600160a01b0384163330856135cf565b826001600160a01b03167fac24935fd910bc682b5ccb1a07b718cadf8cf2f6d1404c4f3ddc3662dae40e2983604051611e199190614b55565b60405180910390a26001600160a01b0383167362b9c7356a2dc64a1969e19c23e4f579f9810aa71415611e5057611e5060006131b2565b505050565b6001600160a01b038116600090815260036020526040812054610c6d90600160301b90046001600160d01b031662093a8061279e565b60165460ff1681565b611e9f816000611017565b50565b6117356135f6565b60098181548110611eb757fe5b6000918252602090912001546001600160e01b0381169150600160e01b900463ffffffff1682565b60075481565b6001600160a01b0381166000908152600b60205260408120600980548391611f3a9162093a80919088908110611f1757fe5b60009182526020909120015463ffffffff600160e01b909104811691906127d516565b8254909150600019015b6001810115611fbb576000611f6562093a80601002858481548110610beb57fe5b905082811415611fa357838281548110611f7b57fe5b600091825260209091200154600160701b90046001600160701b03169450610c6d9350505050565b82811015611fb15750611fbb565b5060001901611f44565b50600095945050505050565b60026000541415611fea5760405162461bcd60e51b8152600401610d10906149d4565b6002600081905550610d31336000808433600061281b565b61200a612ec0565b6001600160a01b031661201b611958565b6001600160a01b0316146120415760405162461bcd60e51b8152600401610d1090614811565b6001600160a01b03831660009081526003602052604090206001015464ffffffffff161561206e57600080fd5b6001600160a01b038316734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b141561209857600080fd5b6002805460018082019092557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace0180546001600160a01b0319166001600160a01b039586169081179091556000908152600360209081526040808320808501805464ffffffffff19164264ffffffffff16908117909155815465ffffffffff0019166101009091021760ff1990811696151596909617905560048252808320959096168252939093529290912080549091169091179055565b60025460609067ffffffffffffffff8111801561216d57600080fd5b506040519080825280602002602001820160405280156121a757816020015b612194614205565b81526020019060019003908161218c5790505b506001600160a01b0383166000908152600a60205260408120805492935091600160701b90046001600160701b0316905b8351811015611577576000600282815481106121f057fe5b9060005260206000200160009054906101000a90046001600160a01b031690508085838151811061221d57fe5b6020908102919091018101516001600160a01b039283169052908216600090815260039091526040902054612267908790839060ff1661118a5786546001600160701b031661118c565b85838151811061227357fe5b6020908102919091018101510152506001016121d8565b600260005414156122ad5760405162461bcd60e51b8152600401610d10906149d4565b600260009081556001600160a01b0384168152600a6020526040812080548592600160701b9091046001600160701b0316905b60025481101561245b576000600282815481106122f957fe5b6000918252602090912001546001600160a01b0316905061231c6110a982612ec4565b6001600160a01b03821660009081526003602052604090206001810180546001600160d01b0393909316600160281b02600160281b600160f81b0319909316929092179091555461237d9061110f9064ffffffffff61010090910416612eb4565b6001600160a01b038281166000908152600360205260409020600101805464ffffffffff191664ffffffffff9390931692909217909155851615612452576001600160a01b0381166000908152600360205260409020546123f3908690839060ff1661118a5786546001600160701b031661118c565b6001600160a01b0386811660008181526006602090815260408083209487168084529482528083209590955560038152848220600101549282526005815284822093825292909252919020600160281b9091046001600160d01b031690555b506001016122e0565b506124809150734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b90503330866135cf565b611379848484600061373e565b60155481565b600660209081526000928352604080842090915290825290205481565b60115481565b6000610c6d82612ec4565b6124c9612ec0565b6001600160a01b03166124da611958565b6001600160a01b0316146125005760405162461bcd60e51b8152600401610d1090614811565b6001600160a01b0381166125265760405162461bcd60e51b8152600401610d1090614629565b6001546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b600954600090600019018161259e62093a80610aa8868261276c565b935060005b6080811015612624578282106125b857612624565b600060026001848601010490506000600982815481106125d457fe5b600091825260209091200154600160e01b900463ffffffff1690508681141561260357509350610ce892505050565b868110156126135781935061261a565b6001820394505b50506001016125a3565b509392505050565b612634612ec0565b6001600160a01b0316612645611958565b6001600160a01b03161461266b5760405162461bcd60e51b8152600401610d1090614811565b6013546001600160a01b03161561275d5760135460408051629032ff60e51b815290516000926001600160a01b0316916312065fe0916004808301926020929190829003018186803b1580156126c057600080fd5b505afa1580156126d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126f891906143b0565b601354604051632e1a7d4d60e01b81529192506001600160a01b031690632e1a7d4d90612729908490600401614b55565b600060405180830381600087803b15801561274357600080fd5b505af1158015612757573d6000803e3d6000fd5b50505050505b6016805460ff19166001179055565b600080821161278d5760405162461bcd60e51b8152600401610d10906145f2565b81838161279657fe5b049392505050565b60008115806127b9575050808202828282816127b657fe5b04145b610c6d5760405162461bcd60e51b8152600401610d1090614a84565b81810181811015610c6d5760405162461bcd60e51b8152600401610d109061475f565b80820382811115610c6d5760405162461bcd60e51b8152600401610d109061458c565b6001600160a01b0386166000908152600a6020526040812080548892600160701b9091046001600160701b0316905b6002548110156129c55760006002828154811061286357fe5b6000918252602090912001546001600160a01b031690506128866110a982612ec4565b6001600160a01b03821660009081526003602052604090206001810180546001600160d01b0393909316600160281b02600160281b600160f81b031990931692909217909155546128e79061110f9064ffffffffff61010090910416612eb4565b6001600160a01b038281166000908152600360205260409020600101805464ffffffffff191664ffffffffff93909316929092179091558516156129bc576001600160a01b03811660009081526003602052604090205461295d908690839060ff1661118a5786546001600160701b031661118c565b6001600160a01b0386811660008181526006602090815260408083209487168084529482528083209590955560038152848220600101549282526005815284822093825292909252919020600160281b9091046001600160d01b031690555b5060010161284a565b5050506001600160a01b0387166000908152600b60209081526040808320600a9092528220815460165492939192829190829060ff1680612a365750612a0b42896127f8565b866001840381548110612a1a57fe5b600091825260209091200154600160e01b900463ffffffff1611155b15612b495784546001600160701b038082169550600160701b909104169250612a5e82613e42565b855463ffffffff91909116600160e01b026001600160e01b039091161785558715612b44576000612aa062093a80610aa881612a9a428e6127f8565b9061276c565b90506000612ae162093a80612a9a8a6001880381548110612abd57fe5b600091825260209091200154859063ffffffff600160e01b9091048116906127f816565b90506000612b08612b008360010160145461279e90919063ffffffff16565b612710613e68565b9050612b3e612710612a9a838c60018a0381548110612b2357fe5b6000918252602090912001546001600160701b03169061279e565b93505050505b612cb7565b8454600160e01b900463ffffffff16805b83811015612c9757612b6c428b6127f8565b888281548110612b7857fe5b600091825260209091200154600160e01b900463ffffffff161115612b9c57612c97565b612bc9888281548110612bab57fe5b6000918252602090912001546001600160701b038881169116613e7e565b9550612bff888281548110612bda57fe5b6000918252602090912001546001600160701b0387811691600160701b900416613e7e565b94508915612c8b576000612c2a62093a80610aa862093a80612a9a8f426127f890919063ffffffff16565b90506000612c4462093a80612a9a8c8681548110612abd57fe5b90506000612c63612b008360010160145461279e90919063ffffffff16565b9050612c85612c7e612710612a9a848f8981548110612b2357fe5b87906127d5565b95505050505b60019182019101612b5a565b50855463ffffffff909116600160e01b026001600160e01b039091161785555b6000846001600160701b031611612ce05760405162461bcd60e51b8152600401610d1090614710565b8454612cf5906001600160701b031685613ead565b85546001600160701b0319166001600160701b0391821617808755612d2391600160701b9091041684613ead565b8554600160701b600160e01b031916600160701b6001600160701b0392831602178655600754612d549186166127f8565b600755600854612d6d906001600160701b0385166127f8565b6008819055508c6001600160a01b03167f2fd83d5e9f5d240bed47a97a24cf354e4047e25edc2da27b01fd95e5e8a0c9a5858e604051612dae929190614af2565b60405180910390a28015612e4857612dce846001600160701b0316613edc565b612dea612dda82613fdd565b6001600160701b03861690613ead565b9350612df889826000614006565b8c6001600160a01b0316896001600160a01b03167f7e7ff29ed04cfb223bc9b02606f69520517c117ee82c9158ed2d96323c1ef38583604051612e3b9190614b55565b60405180910390a3612e6f565b8a15612e6f57612e6f612e6a612710612a9a6001600160701b0388168f61279e565b613edc565b8b15612e9057612e8b8a856001600160701b03168d600161373e565b612ea5565b612ea58a856001600160701b03166001614006565b50505050505050505050505050565b6000610c6d4283613e68565b3390565b600060085460001415612f0357506001600160a01b038116600090815260036020526040902060010154600160281b90046001600160d01b0316610ce8565b6001600160a01b038216600090815260036020526040902054610c6d90612f9b9060ff16612f3357600754612f37565b6008545b6001600160a01b03851660009081526003602052604090208054600190910154612a9a91670de0b6b3a764000091610aa8916001600160d01b03600160301b82041691839164ffffffffff91821691612f9591610100900416612eb4565b906127f8565b6001600160a01b038416600090815260036020526040902060010154600160281b90046001600160d01b0316906127d5565b60006001600160d01b03821115612ff65760405162461bcd60e51b8152600401610d10906145bb565b5090565b600064ffffffffff821115612ff65760405162461bcd60e51b8152600401610d1090614abb565b6001600160a01b03808416600081815260066020908152604080832094871680845294825280832054938352600582528083209483529390529182205461308f919061308990670de0b6b3a764000090612a9a9061308290612f958a612ec4565b879061279e565b906127d5565b90505b9392505050565b611e508363a9059cbb60e01b84846040516024016130b89291906144a7565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261403e565b8015806131775750604051636eb1769f60e11b81526001600160a01b0384169063dd62ed3e906131259030908690600401614469565b60206040518083038186803b15801561313d57600080fd5b505afa158015613151573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061317591906143b0565b155b6131935760405162461bcd60e51b8152600401610d1090614a2e565b611e508363095ea7b360e01b84846040516024016130b89291906144a7565b60165460ff16156131c257611e9f565b6040516370a0823160e01b8152600090734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b906370a08231906131fc903090600401614455565b60206040518083038186803b15801561321457600080fd5b505afa158015613228573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061324c91906143b0565b90506000601360009054906101000a90046001600160a01b03166001600160a01b03166312065fe06040518163ffffffff1660e01b815260040160206040518083038186803b15801561329e57600080fd5b505afa1580156132b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132d691906143b0565b905060006132e483836127d5565b9050806132f357505050611e9f565b600061330582612a9a8561271061279e565b905060006133256002612a9a6011546012546127d590919063ffffffff16565b9050600061333e876012546127d590919063ffffffff16565b905060006133526011548960115403613e68565b9050818411156133e1576000613378613371612710612a9a898861279e565b88906127f8565b601354604051632e1a7d4d60e01b81529192506001600160a01b031690632e1a7d4d906133a9908490600401614b55565b600060405180830381600087803b1580156133c357600080fd5b505af11580156133d7573d6000803e3d6000fd5b5050505050613492565b808410156134925760006133ff87612f95612710612a9a8a8961279e565b60135490915061342e90734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b906001600160a01b031683613099565b601360009054906101000a90046001600160a01b03166001600160a01b0316633a4b66f16040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561347e57600080fd5b505af1158015612ea5573d6000803e3d6000fd5b5050505050505050565b6001600160a01b03821660009081526003602052604090208054610100900464ffffffffff1642106134fe576134d86110a98362093a8061276c565b81546001600160d01b0391909116600160301b0265ffffffffffff909116178155613576565b805460009061351990610100900464ffffffffff16426127f8565b825490915060009061353c908390600160301b90046001600160d01b031661279e565b90506135526110a962093a80612a9a87856127d5565b83546001600160d01b0391909116600160301b0265ffffffffffff90911617835550505b61357f42612ffa565b60018201805464ffffffffff191664ffffffffff929092169190911790556135ad61110f4262093a806127d5565b815464ffffffffff919091166101000265ffffffffff00199091161790555050565b6135f0846323b872dd60e01b8585856040516024016130b893929190614483565b50505050565b600061360d62093a8061308981610aa8428261276c565b600980549192508290600019830183811061362457fe5b600091825260209091200154600160e01b900463ffffffff161015611954575b60098054839190600019810190811061365957fe5b600091825260209091200154600160e01b900463ffffffff161461371757600061369562093a80600960016009805490500381548110611f1757fe5b60408051808201909152600080825263ffffffff9283166020830190815260098054600181018255925291517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af90910180549251909316600160e01b026001600160e01b039182166001600160e01b0319909316929092171617905550613644565b601054600e541461372957601054600e555b600f54600d541461195457600f54600d555050565b6000831161375e5760405162461bcd60e51b8152600401610d109061466f565b600d548211156137805760405162461bcd60e51b8152600401610d1090614697565b60165460ff16156137a35760405162461bcd60e51b8152600401610d10906148a0565b6001600160a01b0384166000908152600a602052604090206137c36135f6565b60006137d5612710612a9a878761279e565b905060006137fe600d546000146137ee57600d546137f1565b60015b600e54612a9a908861279e565b9050600061381461380f88856127f8565b613fdd565b9050600061383561380f61382e612710612a9a8c8861279e565b8a906127d5565b855490915061384d906001600160701b031683613e7e565b85546001600160701b0319166001600160701b039182161780875561387b91600160701b9091041682613e7e565b8554600160701b600160e01b031916600160701b6001600160701b03928316021786556007546138ac9184166127d5565b6007556008546138c5906001600160701b0383166127d5565b60085560006138db62093a80610aa8428261276c565b9050866138f2576138ef8162093a806127d5565b90505b6000613901826293a8006127d5565b6001600160a01b038c166000908152600b602052604090205490915080158061396b57506001600160a01b038c166000908152600b602052604090208054839190600019840190811061395057fe5b600091825260209091200154600160e01b900463ffffffff16105b15613a1a576001600160a01b038c166000908152600b6020908152604080832081516060810183526001600160701b03808b16825289811682860190815263ffffffff808a16958401958652845460018101865594885295909620915191909201805495519351909416600160e01b026001600160e01b03938316600160701b02600160701b600160e01b0319929093166001600160701b031990961695909517161716919091179055613d47565b6001600160a01b038c166000908152600b6020526040902080548391906000198401908110613a4557fe5b600091825260209091200154600160e01b900463ffffffff161115613a6957600019015b6001600160a01b038c166000908152600b6020526040902080548391906000198401908110613a9457fe5b600091825260209091200154600160e01b900463ffffffff161415613b57576001600160a01b038c166000908152600b6020526040812080546000198401908110613adb57fe5b60009182526020909120018054909150613afe906001600160701b031687613e7e565b81546001600160701b0319166001600160701b0391821617808355613b2c91600160701b9091041686613e7e565b81546001600160701b0391909116600160701b02600160701b600160e01b0319909116179055613d47565b506001600160a01b038b166000908152600b60205260408120805491906000198301838110613b8257fe5b906000526020600020019050600b60008e6001600160a01b03166001600160a01b0316815260200190815260200160002060405180606001604052808360000160009054906101000a90046001600160701b03166001600160701b0316815260200183600001600e9054906101000a90046001600160701b03166001600160701b0316815260200183600001601c9054906101000a900463ffffffff1663ffffffff168152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a8154816001600160701b0302191690836001600160701b03160217905550602082015181600001600e6101000a8154816001600160701b0302191690836001600160701b03160217905550604082015181600001601c6101000a81548163ffffffff021916908363ffffffff1602179055505050858160000160006101000a8154816001600160701b0302191690836001600160701b031602179055508481600001600e6101000a8154816001600160701b0302191690836001600160701b031602179055508281600001601c6101000a81548163ffffffff021916908363ffffffff160217905550505b600954600019018915613d5957600019015b600060098281548110613d6857fe5b60009182526020909120018054909150613d94906001600160e01b03166001600160701b0388166140cd565b81546001600160e01b0319166001600160e01b03919091161781558815613de157600c54613de190734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b906001600160a01b03168b613099565b613dec6101f46131b2565b848e6001600160a01b03167f9cfd25589d1eb8ad71e342a86a8524e83522e3936c0803048c08f6d9ad974f408f8a8a604051613e2a93929190614b5e565b60405180910390a35050505050505050505050505050565b600063ffffffff821115612ff65760405162461bcd60e51b8152600401610d109061491c565b6000818310613e775781613092565b5090919050565b8181016001600160701b038083169082161015610c6d5760405162461bcd60e51b8152600401610d109061475f565b8082036001600160701b038084169082161115610c6d5760405162461bcd60e51b8152600401610d109061458c565b6040516370a0823160e01b8152600090734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b906370a0823190613f16903090600401614455565b60206040518083038186803b158015613f2e57600080fd5b505afa158015613f42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f6691906143b0565b905080821115611954576013546001600160a01b0316632e1a7d4d613f8b84846127f8565b6040518263ffffffff1660e01b8152600401613fa79190614b55565b600060405180830381600087803b158015613fc157600080fd5b505af1158015613fd5573d6000803e3d6000fd5b505050505050565b60006001600160701b03821115612ff65760405162461bcd60e51b8152600401610d1090614796565b61400f82613edc565b61402e734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b8484613099565b8015611e5057611e5060006131b2565b6060614093826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166140fc9092919063ffffffff16565b805190915015611e5057808060200190518101906140b1919061437c565b611e505760405162461bcd60e51b8152600401610d1090614953565b8181016001600160e01b038083169082161015610c6d5760405162461bcd60e51b8152600401610d109061475f565b606061308f848460008585614110856141a6565b61412c5760405162461bcd60e51b8152600401610d10906148c2565b60006060866001600160a01b031685876040516141499190614439565b60006040518083038185875af1925050503d8060008114614186576040519150601f19603f3d011682016040523d82523d6000602084013e61418b565b606091505b509150915061419b8282866141ac565b979650505050505050565b3b151590565b606083156141bb575081613092565b8251156141cb5782518084602001fd5b8160405162461bcd60e51b8152600401610d109190614559565b604080516060810182526000808252602082018190529181019190915290565b604080518082019091526000808252602082015290565b80356001600160a01b0381168114610c6d57600080fd5b600060208284031215614244578081fd5b613092838361421c565b60008060408385031215614260578081fd5b61426a848461421c565b9150614279846020850161421c565b90509250929050565b600080600060608486031215614296578081fd5b83356142a181614c39565b925060208401356142b181614c39565b915060408401356142c181614c4e565b809150509250925092565b600080604083850312156142de578182fd5b6142e8848461421c565b915060208301356142f881614c4e565b809150509250929050565b60008060408385031215614315578182fd5b61431f848461421c565b946020939093013593505050565b600080600060608486031215614341578283fd5b61434b858561421c565b95602085013595506040909401359392505050565b600060208284031215614371578081fd5b813561309281614c4e565b60006020828403121561438d578081fd5b815161309281614c4e565b6000602082840312156143a9578081fd5b5035919050565b6000602082840312156143c1578081fd5b5051919050565b600080604083850312156143da578182fd5b82359150614279846020850161421c565b600080604083850312156143fd578182fd5b50508035926020909101359150565b600080600060608486031215614420578283fd5b833592506020840135915060408401356142c181614c39565b6000825161444b818460208701614c0d565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b602080825282518282018190526000919060409081850190868401855b8281101561450b57815180516001600160a01b031685528601518685015292840192908501906001016144dd565b5091979650505050505050565b901515815260200190565b941515855264ffffffffff93841660208601526001600160d01b0392831660408601529216606084015216608082015260a00190565b6000602082528251806020840152614578816040850160208701614c0d565b601f01601f19169190910160400192915050565b602080825260159082015274426f72696e674d6174683a20556e646572666c6f7760581b604082015260600190565b6020808252601c908201527f426f72696e674d6174683a2075696e74323038204f766572666c6f7700000000604082015260600190565b6020808252601c908201527f426f72696e674d6174683a206469766973696f6e206279207a65726f00000000604082015260600190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252600e908201526d043616e6e6f74207374616b6520360941b604082015260600190565b6020808252600e908201526d1bdd995c881b585e081cdc195b9960921b604082015260600190565b60208082526010908201526f1bdd995c881b585e081c185e5b595b9d60821b604082015260600190565b6020808252600d908201526c6f766572206d6178207261746560981b604082015260600190565b6020808252600c908201526b6e6f20657870206c6f636b7360a01b604082015260600190565b6020808252600f908201526e696e76616c6964206164647265737360881b604082015260600190565b60208082526018908201527f426f72696e674d6174683a20416464204f766572666c6f770000000000000000604082015260600190565b6020808252601c908201527f426f72696e674d6174683a2075696e74313132204f766572666c6f7700000000604082015260600190565b602080825260099082015268139bc81c995dd85c9960ba1b604082015260600190565b60208082526007908201526610b0b9b9b4b3b760c91b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601d908201527f43616e6e6f74207769746864726177207374616b696e6720746f6b656e000000604082015260600190565b6020808252600990820152686d696e2064656c617960b81b604082015260600190565b60208082526008908201526739b43aba3237bbb760c11b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252600990820152686d696e2072616e676560b81b604082015260600190565b6020808252601b908201527f426f72696e674d6174683a2075696e743332204f766572666c6f770000000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252601c908201527f43616e6e6f742077697468647261772072657761726420746f6b656e00000000604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252600990820152686d61782072616e676560b81b604082015260600190565b60208082526036908201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60408201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606082015260800190565b60208082526018908201527f426f72696e674d6174683a204d756c204f766572666c6f770000000000000000604082015260600190565b6020808252601b908201527f426f72696e674d6174683a2075696e743430204f766572666c6f770000000000604082015260600190565b6001600160701b039290921682521515602082015260400190565b6001600160701b03938416815291909216602082015263ffffffff909116604082015260600190565b6001600160e01b0392909216825263ffffffff16602082015260400190565b90815260200190565b9283526001600160701b03918216602084015216604082015260600190565b6000608082018683526020868185015260408681860152606060808187015283875180865260a0880191508489019550865b81811015614bee57865180516001600160701b03908116855287820151168785015285015163ffffffff16858401529585019591830191600101614baf565b50909b9a5050505050505050505050565b60ff91909116815260200190565b60005b83811015614c28578181015183820152602001614c10565b838111156135f05750506000910152565b6001600160a01b0381168114611e9f57600080fd5b8015158114611e9f57600080fdfea26469706673582212200daca5079d08a2a2879895b2312c0d991308583c3b5872c6c0d929844700353664736f6c634300060c0033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106103f15760003560e01c8063887c7dc511610215578063bf86d69011610125578063dc01f60d116100b8578063ec5ffac211610087578063ec5ffac2146107e8578063f1229777146107f0578063f2fde38b14610803578063f826159714610816578063fc0e74d114610829576103f1565b8063dc01f60d1461079a578063e2ab691d146107ba578063e432488d146107cd578063e70b9e27146107d5576103f1565b8063ca5c7b91116100f4578063ca5c7b9114610759578063cb1b9a7414610761578063d36f12fb14610774578063d3c45c7614610787576103f1565b8063bf86d69014610715578063c00007b01461071d578063c1009f4b14610730578063c6b61e4c14610738576103f1565b8063a81653c9116101a8578063b187bc2211610177578063b187bc22146106d7578063b5c6b453146106df578063b5ed7a66146106e7578063b66503cf146106ef578063bcd1101414610702576103f1565b8063a81653c9146106a1578063a98e05bb146106b4578063aa33fedb146106bc578063ae8d4825146106cf576103f1565b806395d89b41116101e457806395d89b411461067657806396ce07951461067e5780639bdc7467146106865780639dd373b91461068e576103f1565b8063887c7dc5146106355780638980f11f146106485780638c9bd1b51461065b5780638da5cb5b1461066e576103f1565b8063638634ee1161031057806370b36d79116102a35780637bb7bed1116102725780637bb7bed1146106025780637bd48c7c1461061557806382480df91461061d578063829965cc146106255780638757b15b1461062d576103f1565b806370b36d79146105d7578063715018a6146105ea57806372f702f3146105f257806375aadf61146105fa576103f1565b806368edd2bb116102df57806368edd2bb1461058b5780637035ab981461059e5780637050ccd9146105b157806370a08231146105c4576103f1565b8063638634ee1461054a57806363f1c8e21461055d578063648bb8ad146105705780636724c91014610578576103f1565b80632fe871081161038857806339fc97131161035757806339fc9713146104eb57806348e5d9f81461050b57806354fd4d501461052f5780635935573614610537576103f1565b80632fe87108146104a6578063312ff839146104b9578063313ce567146104ce578063386a9525146104e3576103f1565b80631c607395116103c45780631c6073951461045457806322f80d111461046757806327e235e31461047c5780632e9564e41461049e576103f1565b806304554443146103f65780630483a7f61461041457806306fdde031461043757806318160ddd1461044c575b600080fd5b6103fe610831565b60405161040b9190614b55565b60405180910390f35b610427610422366004614233565b610838565b60405161040b9493929190614b7d565b61043f6109fe565b60405161040b9190614559565b6103fe610a94565b6103fe6104623660046143c8565b610b6a565b61046f610c73565b60405161040b9190614455565b61048f61048a366004614233565b610c82565b60405161040b93929190614b0d565b6103fe610cb8565b6103fe6104b4366004614233565b610cbe565b6104cc6104c7366004614360565b610ced565b005b6104d6610d39565b60405161040b9190614bff565b6103fe610d5d565b6104fe6104f936600461424e565b610d64565b60405161040b9190614518565b61051e610519366004614233565b610d84565b60405161040b959493929190614523565b6103fe610dd0565b6103fe610545366004614233565b610dd5565b6103fe610558366004614233565b610df9565b6104cc61056b3660046143eb565b610e27565b6103fe610eb4565b6104cc610586366004614282565b610eba565b6103fe610599366004614233565b610f5f565b6103fe6105ac36600461424e565b610ffa565b6104cc6105bf3660046142cc565b611017565b6103fe6105d2366004614233565b611384565b6103fe6105e5366004614398565b6114a8565b6104cc61157f565b61046f611608565b6103fe611620565b61046f610610366004614398565b611626565b6103fe61164d565b61046f611653565b6103fe61166b565b6104cc611671565b6104cc610643366004614233565b611737565b6104cc610656366004614303565b611788565b6104cc6106693660046143eb565b61189d565b61046f611958565b61043f611967565b6103fe6119c8565b6103fe6119ce565b6104cc61069c366004614233565b6119d4565b6104cc6106af36600461440c565b611a5e565b61046f611b2f565b61048f6106ca366004614303565b611b3e565b61046f611b8a565b6103fe611ba2565b6103fe611ba8565b6103fe611bae565b6104cc6106fd366004614303565b611bb4565b6103fe610710366004614233565b611e55565b6104fe611e8b565b6104cc61072b366004614233565b611e94565b6104cc611ea2565b61074b610746366004614398565b611eaa565b60405161040b929190614b36565b6103fe611edf565b6103fe61076f3660046143c8565b611ee5565b6104cc610782366004614233565b611fc7565b6104cc610795366004614282565b612002565b6107ad6107a8366004614233565b612151565b60405161040b91906144c0565b6104cc6107c836600461432d565b61228a565b6103fe61248d565b6103fe6107e336600461424e565b612493565b6103fe6124b0565b6103fe6107fe366004614233565b6124b6565b6104cc610811366004614233565b6124c1565b6103fe610824366004614398565b612582565b6104cc61262c565b6293a80081565b6001600160a01b0381166000908152600b60209081526040808320600a9092528220805483928392606092600160e01b900463ffffffff1684815b84548110156109e6574285828154811061088957fe5b600091825260209091200154600160e01b900463ffffffff1611156109b0578161090657845481900367ffffffffffffffff811180156108c857600080fd5b5060405190808252806020026020018201604052801561090257816020015b6108ef6141e5565b8152602001906001900390816108e75790505b5095505b84818154811061091257fe5b60009182526020918290206040805160608101825291909201546001600160701b038082168352600160701b8204169382019390935263ffffffff600160e01b9093049290921690820152865187908490811061096b57fe5b602002602001018190525081806001019250506109a985828154811061098d57fe5b60009182526020909120015488906001600160701b03166127d5565b96506109de565b6109db8582815481106109bf57fe5b60009182526020909120015489906001600160701b03166127d5565b97505b600101610873565b505090546001600160701b0316955050509193509193565b60178054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610a8a5780601f10610a5f57610100808354040283529160200191610a8a565b820191906000526020600020905b815481529060010190602001808311610a6d57829003601f168201915b5050505050905090565b600080610aae62093a80610aa8428261276c565b9061279e565b90506000610abf826293a8006127f8565b6009805491925083906000198301838110610ad657fe5b600091825260209091200154600160e01b900463ffffffff161115610afa57600019015b60001981015b6001810115610b6357600060098281548110610b1857fe5b60009182526020909120018054909150600160e01b900463ffffffff168410610b415750610b63565b8054610b579087906001600160e01b03166127d5565b95505060001901610b00565b5050505090565b6001600160a01b0381166000908152600b602052604081206009805483919086908110610b9357fe5b600091825260208220015463ffffffff600160e01b90910481169250610bc09083906293a800906127f816565b8354909150600019015b6001810115610c68576000610c0e62093a80601002868481548110610beb57fe5b60009182526020909120015463ffffffff600160e01b909104811691906127f816565b9050838111610c5e5782811115610c5857610c51858381548110610c2e57fe5b6000918252602090912001548790600160701b90046001600160701b03166127d5565b9550610c5e565b50610c68565b5060001901610bca565b505050505b92915050565b6013546001600160a01b031681565b600a602052600090815260409020546001600160701b0380821691600160701b810490911690600160e01b900463ffffffff1683565b600e5481565b6001600160a01b0381166000908152600a6020526040902054600160701b90046001600160701b03165b919050565b60026000541415610d195760405162461bcd60e51b8152600401610d10906149d4565b60405180910390fd5b6002600081905550610d31338260003333600061281b565b506001600055565b7f000000000000000000000000000000000000000000000000000000000000001290565b62093a8081565b600460209081526000928352604080842090915290825290205460ff1681565b6003602052600090815260409020805460019091015460ff82169164ffffffffff61010082048116926001600160d01b03600160301b90930483169291811691600160281b9091041685565b600290565b6001600160a01b03166000908152600a60205260409020546001600160701b031690565b6001600160a01b038116600090815260036020526040812054610c6d90610100900464ffffffffff16612eb4565b610e2f612ec0565b6001600160a01b0316610e40611958565b6001600160a01b031614610e665760405162461bcd60e51b8152600401610d1090614811565b6101f4821115610e885760405162461bcd60e51b8152600401610d10906146e9565b6002811015610ea95760405162461bcd60e51b8152600401610d109061487d565b601491909155601555565b6101f481565b610ec2612ec0565b6001600160a01b0316610ed3611958565b6001600160a01b031614610ef95760405162461bcd60e51b8152600401610d1090614811565b6001600160a01b03831660009081526003602052604090206001015464ffffffffff16610f2557600080fd5b6001600160a01b03928316600090815260046020908152604080832094909516825292909252919020805460ff1916911515919091179055565b6001600160a01b0381166000908152600b60205260408120805482610f8b62093a80610aa8428261276c565b9050600082118015610fb4575080610fb262093a80601002856001860381548110610beb57fe5b115b15610fef57826001830381548110610fc857fe5b600091825260209091200154600160701b90046001600160701b03169350610ce892505050565b506000949350505050565b600560209081526000928352604080842090915290825290205481565b6002600054141561103a5760405162461bcd60e51b8152600401610d10906149d4565b600260009081556001600160a01b0383168152600a6020526040812080548492600160701b9091046001600160701b0316905b6002548110156111f95760006002828154811061108657fe5b6000918252602090912001546001600160a01b031690506110ae6110a982612ec4565b612fcd565b6001600160a01b03821660009081526003602052604090206001810180546001600160d01b0393909316600160281b02600160281b600160f81b031990931692909217909155546111149061110f9064ffffffffff61010090910416612eb4565b612ffa565b6001600160a01b038281166000908152600360205260409020600101805464ffffffffff191664ffffffffff93909316929092179091558516156111f0576001600160a01b038116600090815260036020526040902054611191908690839060ff1661118a5786546001600160701b031661118c565b855b613021565b6001600160a01b0386811660008181526006602090815260408083209487168084529482528083209590955560038152848220600101549282526005815284822093825292909252919020600160281b9091046001600160d01b031690555b5060010161106d565b50505060005b6002548110156113795760006002828154811061121857fe5b60009182526020808320909101546001600160a01b03888116845260068352604080852091909216808552925290912054909150801561136f576001600160a01b038087166000908152600660209081526040808320938616808452939091528120557362b9c7356a2dc64a1969e19c23e4f579f9810aa714801561129a5750845b1561130f576040516305dc812160e31b8152733fe65692bfcd0e6cf84cb1e7d24108e434a7587e90632ee40908906112d890899085906004016144a7565b600060405180830381600087803b1580156112f257600080fd5b505af1158015611306573d6000803e3d6000fd5b50505050611323565b6113236001600160a01b0383168783613099565b816001600160a01b0316866001600160a01b03167f540798df468d7b23d11f156fdb954cb19ad414d150722a7b6d55ba369dea792e836040516113669190614b55565b60405180910390a35b50506001016111ff565b505060016000555050565b6001600160a01b0381166000908152600b60209081526040808320600a90925290912080548254600160701b82046001600160701b0316939291600160e01b900463ffffffff1690815b8181101561144757428582815481106113e357fe5b600091825260209091200154600160e01b900463ffffffff161161143a5761143385828154811061141057fe5b6000918252602090912001548790600160701b90046001600160701b03166127f8565b955061143f565b611447565b6001016113ce565b50600061145b62093a80610aa8428261276c565b905060008211801561148457508061148262093a80601002876001860381548110610beb57fe5b115b1561149e5761149b85600184038154811061141057fe5b95505b5050505050919050565b6000806114e962093a80610aa862093a80600987815481106114c657fe5b60009182526020909120015463ffffffff600160e01b9091048116919061276c16565b905060006114fa826293a8006127f8565b9050835b60018101156115775760006009828154811061151657fe5b60009182526020909120018054909150600160e01b900463ffffffff16831061153f5750611577565b61156b6009838154811061154f57fe5b60009182526020909120015486906001600160e01b03166127d5565b945050600019016114fe565b505050919050565b611587612ec0565b6001600160a01b0316611598611958565b6001600160a01b0316146115be5760405162461bcd60e51b8152600401610d1090614811565b6001546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600180546001600160a01b0319169055565b734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b81565b60085481565b6002818154811061163357fe5b6000918252602090912001546001600160a01b0316905081565b600f5481565b7362b9c7356a2dc64a1969e19c23e4f579f9810aa781565b60095490565b6116a57362b9c7356a2dc64a1969e19c23e4f579f9810aa7733fe65692bfcd0e6cf84cb1e7d24108e434a7587e60006130ef565b6116da7362b9c7356a2dc64a1969e19c23e4f579f9810aa7733fe65692bfcd0e6cf84cb1e7d24108e434a7587e6000196130ef565b60135461170790734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b906001600160a01b031660006130ef565b60135461173590734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b906001600160a01b03166000196130ef565b565b6002600054141561175a5760405162461bcd60e51b8152600401610d10906149d4565b6002600081905550610d3181600080843361178360155462093a8061279e90919063ffffffff16565b61281b565b611790612ec0565b6001600160a01b03166117a1611958565b6001600160a01b0316146117c75760405162461bcd60e51b8152600401610d1090614811565b6001600160a01b038216734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b14156118045760405162461bcd60e51b8152600401610d1090614846565b6001600160a01b03821660009081526003602052604090206001015464ffffffffff16156118445760405162461bcd60e51b8152600401610d109061499d565b61186061184f611958565b6001600160a01b0384169083613099565b7f8c1256b8896378cd5044f80c202f9772b9d77dc85c8a6eb51967210b09bfaa2882826040516118919291906144a7565b60405180910390a15050565b6118a5612ec0565b6001600160a01b03166118b6611958565b6001600160a01b0316146118dc5760405162461bcd60e51b8152600401610d1090614811565b6127108211156118fe5760405162461bcd60e51b8152600401610d10906148f9565b6127108111156119205760405162461bcd60e51b8152600401610d1090614a0b565b808211156119405760405162461bcd60e51b8152600401610d10906148f9565b6011829055601281905561195460006131b2565b5050565b6001546001600160a01b031690565b60188054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610a8a5780601f10610a5f57610100808354040283529160200191610a8a565b61271081565b60145481565b6119dc612ec0565b6001600160a01b03166119ed611958565b6001600160a01b031614611a135760405162461bcd60e51b8152600401610d1090614811565b6013546001600160a01b031615611a3c5760405162461bcd60e51b8152600401610d10906147f0565b601380546001600160a01b0319166001600160a01b0392909216919091179055565b611a66612ec0565b6001600160a01b0316611a77611958565b6001600160a01b031614611a9d5760405162461bcd60e51b8152600401610d1090614811565b6105dc8310611abe5760405162461bcd60e51b8152600401610d10906146bf565b6175308210611adf5760405162461bcd60e51b8152600401610d10906146e9565b6001600160a01b038116611b055760405162461bcd60e51b8152600401610d1090614736565b600f92909255601055600c80546001600160a01b0319166001600160a01b03909216919091179055565b600c546001600160a01b031681565b600b6020528160005260406000208181548110611b5757fe5b6000918252602090912001546001600160701b038082169350600160701b8204169150600160e01b900463ffffffff1683565b733fe65692bfcd0e6cf84cb1e7d24108e434a7587e81565b600d5481565b60125481565b60105481565b6000808052600a6020527f13da86008ba1c6922daee3e07db95305ef49ebced9f5467a0b8613fcc6b343e38054600160701b90046001600160701b0316825b600254811015611d6e57600060028281548110611c0c57fe5b6000918252602090912001546001600160a01b03169050611c2f6110a982612ec4565b6001600160a01b03821660009081526003602052604090206001810180546001600160d01b0393909316600160281b02600160281b600160f81b03199093169290921790915554611c909061110f9064ffffffffff61010090910416612eb4565b6001600160a01b038281166000908152600360205260409020600101805464ffffffffff191664ffffffffff9390931692909217909155851615611d65576001600160a01b038116600090815260036020526040902054611d06908690839060ff1661118a5786546001600160701b031661118c565b6001600160a01b0386811660008181526006602090815260408083209487168084529482528083209590955560038152848220600101549282526005815284822093825292909252919020600160281b9091046001600160d01b031690555b50600101611bf3565b5050506001600160a01b038316600090815260046020908152604080832033845290915290205460ff16611da157600080fd5b60008211611dc15760405162461bcd60e51b8152600401610d10906147cd565b611dcb838361349c565b611de06001600160a01b0384163330856135cf565b826001600160a01b03167fac24935fd910bc682b5ccb1a07b718cadf8cf2f6d1404c4f3ddc3662dae40e2983604051611e199190614b55565b60405180910390a26001600160a01b0383167362b9c7356a2dc64a1969e19c23e4f579f9810aa71415611e5057611e5060006131b2565b505050565b6001600160a01b038116600090815260036020526040812054610c6d90600160301b90046001600160d01b031662093a8061279e565b60165460ff1681565b611e9f816000611017565b50565b6117356135f6565b60098181548110611eb757fe5b6000918252602090912001546001600160e01b0381169150600160e01b900463ffffffff1682565b60075481565b6001600160a01b0381166000908152600b60205260408120600980548391611f3a9162093a80919088908110611f1757fe5b60009182526020909120015463ffffffff600160e01b909104811691906127d516565b8254909150600019015b6001810115611fbb576000611f6562093a80601002858481548110610beb57fe5b905082811415611fa357838281548110611f7b57fe5b600091825260209091200154600160701b90046001600160701b03169450610c6d9350505050565b82811015611fb15750611fbb565b5060001901611f44565b50600095945050505050565b60026000541415611fea5760405162461bcd60e51b8152600401610d10906149d4565b6002600081905550610d31336000808433600061281b565b61200a612ec0565b6001600160a01b031661201b611958565b6001600160a01b0316146120415760405162461bcd60e51b8152600401610d1090614811565b6001600160a01b03831660009081526003602052604090206001015464ffffffffff161561206e57600080fd5b6001600160a01b038316734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b141561209857600080fd5b6002805460018082019092557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace0180546001600160a01b0319166001600160a01b039586169081179091556000908152600360209081526040808320808501805464ffffffffff19164264ffffffffff16908117909155815465ffffffffff0019166101009091021760ff1990811696151596909617905560048252808320959096168252939093529290912080549091169091179055565b60025460609067ffffffffffffffff8111801561216d57600080fd5b506040519080825280602002602001820160405280156121a757816020015b612194614205565b81526020019060019003908161218c5790505b506001600160a01b0383166000908152600a60205260408120805492935091600160701b90046001600160701b0316905b8351811015611577576000600282815481106121f057fe5b9060005260206000200160009054906101000a90046001600160a01b031690508085838151811061221d57fe5b6020908102919091018101516001600160a01b039283169052908216600090815260039091526040902054612267908790839060ff1661118a5786546001600160701b031661118c565b85838151811061227357fe5b6020908102919091018101510152506001016121d8565b600260005414156122ad5760405162461bcd60e51b8152600401610d10906149d4565b600260009081556001600160a01b0384168152600a6020526040812080548592600160701b9091046001600160701b0316905b60025481101561245b576000600282815481106122f957fe5b6000918252602090912001546001600160a01b0316905061231c6110a982612ec4565b6001600160a01b03821660009081526003602052604090206001810180546001600160d01b0393909316600160281b02600160281b600160f81b0319909316929092179091555461237d9061110f9064ffffffffff61010090910416612eb4565b6001600160a01b038281166000908152600360205260409020600101805464ffffffffff191664ffffffffff9390931692909217909155851615612452576001600160a01b0381166000908152600360205260409020546123f3908690839060ff1661118a5786546001600160701b031661118c565b6001600160a01b0386811660008181526006602090815260408083209487168084529482528083209590955560038152848220600101549282526005815284822093825292909252919020600160281b9091046001600160d01b031690555b506001016122e0565b506124809150734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b90503330866135cf565b611379848484600061373e565b60155481565b600660209081526000928352604080842090915290825290205481565b60115481565b6000610c6d82612ec4565b6124c9612ec0565b6001600160a01b03166124da611958565b6001600160a01b0316146125005760405162461bcd60e51b8152600401610d1090614811565b6001600160a01b0381166125265760405162461bcd60e51b8152600401610d1090614629565b6001546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b600954600090600019018161259e62093a80610aa8868261276c565b935060005b6080811015612624578282106125b857612624565b600060026001848601010490506000600982815481106125d457fe5b600091825260209091200154600160e01b900463ffffffff1690508681141561260357509350610ce892505050565b868110156126135781935061261a565b6001820394505b50506001016125a3565b509392505050565b612634612ec0565b6001600160a01b0316612645611958565b6001600160a01b03161461266b5760405162461bcd60e51b8152600401610d1090614811565b6013546001600160a01b03161561275d5760135460408051629032ff60e51b815290516000926001600160a01b0316916312065fe0916004808301926020929190829003018186803b1580156126c057600080fd5b505afa1580156126d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126f891906143b0565b601354604051632e1a7d4d60e01b81529192506001600160a01b031690632e1a7d4d90612729908490600401614b55565b600060405180830381600087803b15801561274357600080fd5b505af1158015612757573d6000803e3d6000fd5b50505050505b6016805460ff19166001179055565b600080821161278d5760405162461bcd60e51b8152600401610d10906145f2565b81838161279657fe5b049392505050565b60008115806127b9575050808202828282816127b657fe5b04145b610c6d5760405162461bcd60e51b8152600401610d1090614a84565b81810181811015610c6d5760405162461bcd60e51b8152600401610d109061475f565b80820382811115610c6d5760405162461bcd60e51b8152600401610d109061458c565b6001600160a01b0386166000908152600a6020526040812080548892600160701b9091046001600160701b0316905b6002548110156129c55760006002828154811061286357fe5b6000918252602090912001546001600160a01b031690506128866110a982612ec4565b6001600160a01b03821660009081526003602052604090206001810180546001600160d01b0393909316600160281b02600160281b600160f81b031990931692909217909155546128e79061110f9064ffffffffff61010090910416612eb4565b6001600160a01b038281166000908152600360205260409020600101805464ffffffffff191664ffffffffff93909316929092179091558516156129bc576001600160a01b03811660009081526003602052604090205461295d908690839060ff1661118a5786546001600160701b031661118c565b6001600160a01b0386811660008181526006602090815260408083209487168084529482528083209590955560038152848220600101549282526005815284822093825292909252919020600160281b9091046001600160d01b031690555b5060010161284a565b5050506001600160a01b0387166000908152600b60209081526040808320600a9092528220815460165492939192829190829060ff1680612a365750612a0b42896127f8565b866001840381548110612a1a57fe5b600091825260209091200154600160e01b900463ffffffff1611155b15612b495784546001600160701b038082169550600160701b909104169250612a5e82613e42565b855463ffffffff91909116600160e01b026001600160e01b039091161785558715612b44576000612aa062093a80610aa881612a9a428e6127f8565b9061276c565b90506000612ae162093a80612a9a8a6001880381548110612abd57fe5b600091825260209091200154859063ffffffff600160e01b9091048116906127f816565b90506000612b08612b008360010160145461279e90919063ffffffff16565b612710613e68565b9050612b3e612710612a9a838c60018a0381548110612b2357fe5b6000918252602090912001546001600160701b03169061279e565b93505050505b612cb7565b8454600160e01b900463ffffffff16805b83811015612c9757612b6c428b6127f8565b888281548110612b7857fe5b600091825260209091200154600160e01b900463ffffffff161115612b9c57612c97565b612bc9888281548110612bab57fe5b6000918252602090912001546001600160701b038881169116613e7e565b9550612bff888281548110612bda57fe5b6000918252602090912001546001600160701b0387811691600160701b900416613e7e565b94508915612c8b576000612c2a62093a80610aa862093a80612a9a8f426127f890919063ffffffff16565b90506000612c4462093a80612a9a8c8681548110612abd57fe5b90506000612c63612b008360010160145461279e90919063ffffffff16565b9050612c85612c7e612710612a9a848f8981548110612b2357fe5b87906127d5565b95505050505b60019182019101612b5a565b50855463ffffffff909116600160e01b026001600160e01b039091161785555b6000846001600160701b031611612ce05760405162461bcd60e51b8152600401610d1090614710565b8454612cf5906001600160701b031685613ead565b85546001600160701b0319166001600160701b0391821617808755612d2391600160701b9091041684613ead565b8554600160701b600160e01b031916600160701b6001600160701b0392831602178655600754612d549186166127f8565b600755600854612d6d906001600160701b0385166127f8565b6008819055508c6001600160a01b03167f2fd83d5e9f5d240bed47a97a24cf354e4047e25edc2da27b01fd95e5e8a0c9a5858e604051612dae929190614af2565b60405180910390a28015612e4857612dce846001600160701b0316613edc565b612dea612dda82613fdd565b6001600160701b03861690613ead565b9350612df889826000614006565b8c6001600160a01b0316896001600160a01b03167f7e7ff29ed04cfb223bc9b02606f69520517c117ee82c9158ed2d96323c1ef38583604051612e3b9190614b55565b60405180910390a3612e6f565b8a15612e6f57612e6f612e6a612710612a9a6001600160701b0388168f61279e565b613edc565b8b15612e9057612e8b8a856001600160701b03168d600161373e565b612ea5565b612ea58a856001600160701b03166001614006565b50505050505050505050505050565b6000610c6d4283613e68565b3390565b600060085460001415612f0357506001600160a01b038116600090815260036020526040902060010154600160281b90046001600160d01b0316610ce8565b6001600160a01b038216600090815260036020526040902054610c6d90612f9b9060ff16612f3357600754612f37565b6008545b6001600160a01b03851660009081526003602052604090208054600190910154612a9a91670de0b6b3a764000091610aa8916001600160d01b03600160301b82041691839164ffffffffff91821691612f9591610100900416612eb4565b906127f8565b6001600160a01b038416600090815260036020526040902060010154600160281b90046001600160d01b0316906127d5565b60006001600160d01b03821115612ff65760405162461bcd60e51b8152600401610d10906145bb565b5090565b600064ffffffffff821115612ff65760405162461bcd60e51b8152600401610d1090614abb565b6001600160a01b03808416600081815260066020908152604080832094871680845294825280832054938352600582528083209483529390529182205461308f919061308990670de0b6b3a764000090612a9a9061308290612f958a612ec4565b879061279e565b906127d5565b90505b9392505050565b611e508363a9059cbb60e01b84846040516024016130b89291906144a7565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261403e565b8015806131775750604051636eb1769f60e11b81526001600160a01b0384169063dd62ed3e906131259030908690600401614469565b60206040518083038186803b15801561313d57600080fd5b505afa158015613151573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061317591906143b0565b155b6131935760405162461bcd60e51b8152600401610d1090614a2e565b611e508363095ea7b360e01b84846040516024016130b89291906144a7565b60165460ff16156131c257611e9f565b6040516370a0823160e01b8152600090734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b906370a08231906131fc903090600401614455565b60206040518083038186803b15801561321457600080fd5b505afa158015613228573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061324c91906143b0565b90506000601360009054906101000a90046001600160a01b03166001600160a01b03166312065fe06040518163ffffffff1660e01b815260040160206040518083038186803b15801561329e57600080fd5b505afa1580156132b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132d691906143b0565b905060006132e483836127d5565b9050806132f357505050611e9f565b600061330582612a9a8561271061279e565b905060006133256002612a9a6011546012546127d590919063ffffffff16565b9050600061333e876012546127d590919063ffffffff16565b905060006133526011548960115403613e68565b9050818411156133e1576000613378613371612710612a9a898861279e565b88906127f8565b601354604051632e1a7d4d60e01b81529192506001600160a01b031690632e1a7d4d906133a9908490600401614b55565b600060405180830381600087803b1580156133c357600080fd5b505af11580156133d7573d6000803e3d6000fd5b5050505050613492565b808410156134925760006133ff87612f95612710612a9a8a8961279e565b60135490915061342e90734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b906001600160a01b031683613099565b601360009054906101000a90046001600160a01b03166001600160a01b0316633a4b66f16040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561347e57600080fd5b505af1158015612ea5573d6000803e3d6000fd5b5050505050505050565b6001600160a01b03821660009081526003602052604090208054610100900464ffffffffff1642106134fe576134d86110a98362093a8061276c565b81546001600160d01b0391909116600160301b0265ffffffffffff909116178155613576565b805460009061351990610100900464ffffffffff16426127f8565b825490915060009061353c908390600160301b90046001600160d01b031661279e565b90506135526110a962093a80612a9a87856127d5565b83546001600160d01b0391909116600160301b0265ffffffffffff90911617835550505b61357f42612ffa565b60018201805464ffffffffff191664ffffffffff929092169190911790556135ad61110f4262093a806127d5565b815464ffffffffff919091166101000265ffffffffff00199091161790555050565b6135f0846323b872dd60e01b8585856040516024016130b893929190614483565b50505050565b600061360d62093a8061308981610aa8428261276c565b600980549192508290600019830183811061362457fe5b600091825260209091200154600160e01b900463ffffffff161015611954575b60098054839190600019810190811061365957fe5b600091825260209091200154600160e01b900463ffffffff161461371757600061369562093a80600960016009805490500381548110611f1757fe5b60408051808201909152600080825263ffffffff9283166020830190815260098054600181018255925291517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af90910180549251909316600160e01b026001600160e01b039182166001600160e01b0319909316929092171617905550613644565b601054600e541461372957601054600e555b600f54600d541461195457600f54600d555050565b6000831161375e5760405162461bcd60e51b8152600401610d109061466f565b600d548211156137805760405162461bcd60e51b8152600401610d1090614697565b60165460ff16156137a35760405162461bcd60e51b8152600401610d10906148a0565b6001600160a01b0384166000908152600a602052604090206137c36135f6565b60006137d5612710612a9a878761279e565b905060006137fe600d546000146137ee57600d546137f1565b60015b600e54612a9a908861279e565b9050600061381461380f88856127f8565b613fdd565b9050600061383561380f61382e612710612a9a8c8861279e565b8a906127d5565b855490915061384d906001600160701b031683613e7e565b85546001600160701b0319166001600160701b039182161780875561387b91600160701b9091041682613e7e565b8554600160701b600160e01b031916600160701b6001600160701b03928316021786556007546138ac9184166127d5565b6007556008546138c5906001600160701b0383166127d5565b60085560006138db62093a80610aa8428261276c565b9050866138f2576138ef8162093a806127d5565b90505b6000613901826293a8006127d5565b6001600160a01b038c166000908152600b602052604090205490915080158061396b57506001600160a01b038c166000908152600b602052604090208054839190600019840190811061395057fe5b600091825260209091200154600160e01b900463ffffffff16105b15613a1a576001600160a01b038c166000908152600b6020908152604080832081516060810183526001600160701b03808b16825289811682860190815263ffffffff808a16958401958652845460018101865594885295909620915191909201805495519351909416600160e01b026001600160e01b03938316600160701b02600160701b600160e01b0319929093166001600160701b031990961695909517161716919091179055613d47565b6001600160a01b038c166000908152600b6020526040902080548391906000198401908110613a4557fe5b600091825260209091200154600160e01b900463ffffffff161115613a6957600019015b6001600160a01b038c166000908152600b6020526040902080548391906000198401908110613a9457fe5b600091825260209091200154600160e01b900463ffffffff161415613b57576001600160a01b038c166000908152600b6020526040812080546000198401908110613adb57fe5b60009182526020909120018054909150613afe906001600160701b031687613e7e565b81546001600160701b0319166001600160701b0391821617808355613b2c91600160701b9091041686613e7e565b81546001600160701b0391909116600160701b02600160701b600160e01b0319909116179055613d47565b506001600160a01b038b166000908152600b60205260408120805491906000198301838110613b8257fe5b906000526020600020019050600b60008e6001600160a01b03166001600160a01b0316815260200190815260200160002060405180606001604052808360000160009054906101000a90046001600160701b03166001600160701b0316815260200183600001600e9054906101000a90046001600160701b03166001600160701b0316815260200183600001601c9054906101000a900463ffffffff1663ffffffff168152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a8154816001600160701b0302191690836001600160701b03160217905550602082015181600001600e6101000a8154816001600160701b0302191690836001600160701b03160217905550604082015181600001601c6101000a81548163ffffffff021916908363ffffffff1602179055505050858160000160006101000a8154816001600160701b0302191690836001600160701b031602179055508481600001600e6101000a8154816001600160701b0302191690836001600160701b031602179055508281600001601c6101000a81548163ffffffff021916908363ffffffff160217905550505b600954600019018915613d5957600019015b600060098281548110613d6857fe5b60009182526020909120018054909150613d94906001600160e01b03166001600160701b0388166140cd565b81546001600160e01b0319166001600160e01b03919091161781558815613de157600c54613de190734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b906001600160a01b03168b613099565b613dec6101f46131b2565b848e6001600160a01b03167f9cfd25589d1eb8ad71e342a86a8524e83522e3936c0803048c08f6d9ad974f408f8a8a604051613e2a93929190614b5e565b60405180910390a35050505050505050505050505050565b600063ffffffff821115612ff65760405162461bcd60e51b8152600401610d109061491c565b6000818310613e775781613092565b5090919050565b8181016001600160701b038083169082161015610c6d5760405162461bcd60e51b8152600401610d109061475f565b8082036001600160701b038084169082161115610c6d5760405162461bcd60e51b8152600401610d109061458c565b6040516370a0823160e01b8152600090734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b906370a0823190613f16903090600401614455565b60206040518083038186803b158015613f2e57600080fd5b505afa158015613f42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f6691906143b0565b905080821115611954576013546001600160a01b0316632e1a7d4d613f8b84846127f8565b6040518263ffffffff1660e01b8152600401613fa79190614b55565b600060405180830381600087803b158015613fc157600080fd5b505af1158015613fd5573d6000803e3d6000fd5b505050505050565b60006001600160701b03821115612ff65760405162461bcd60e51b8152600401610d1090614796565b61400f82613edc565b61402e734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b8484613099565b8015611e5057611e5060006131b2565b6060614093826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166140fc9092919063ffffffff16565b805190915015611e5057808060200190518101906140b1919061437c565b611e505760405162461bcd60e51b8152600401610d1090614953565b8181016001600160e01b038083169082161015610c6d5760405162461bcd60e51b8152600401610d109061475f565b606061308f848460008585614110856141a6565b61412c5760405162461bcd60e51b8152600401610d10906148c2565b60006060866001600160a01b031685876040516141499190614439565b60006040518083038185875af1925050503d8060008114614186576040519150601f19603f3d011682016040523d82523d6000602084013e61418b565b606091505b509150915061419b8282866141ac565b979650505050505050565b3b151590565b606083156141bb575081613092565b8251156141cb5782518084602001fd5b8160405162461bcd60e51b8152600401610d109190614559565b604080516060810182526000808252602082018190529181019190915290565b604080518082019091526000808252602082015290565b80356001600160a01b0381168114610c6d57600080fd5b600060208284031215614244578081fd5b613092838361421c565b60008060408385031215614260578081fd5b61426a848461421c565b9150614279846020850161421c565b90509250929050565b600080600060608486031215614296578081fd5b83356142a181614c39565b925060208401356142b181614c39565b915060408401356142c181614c4e565b809150509250925092565b600080604083850312156142de578182fd5b6142e8848461421c565b915060208301356142f881614c4e565b809150509250929050565b60008060408385031215614315578182fd5b61431f848461421c565b946020939093013593505050565b600080600060608486031215614341578283fd5b61434b858561421c565b95602085013595506040909401359392505050565b600060208284031215614371578081fd5b813561309281614c4e565b60006020828403121561438d578081fd5b815161309281614c4e565b6000602082840312156143a9578081fd5b5035919050565b6000602082840312156143c1578081fd5b5051919050565b600080604083850312156143da578182fd5b82359150614279846020850161421c565b600080604083850312156143fd578182fd5b50508035926020909101359150565b600080600060608486031215614420578283fd5b833592506020840135915060408401356142c181614c39565b6000825161444b818460208701614c0d565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b602080825282518282018190526000919060409081850190868401855b8281101561450b57815180516001600160a01b031685528601518685015292840192908501906001016144dd565b5091979650505050505050565b901515815260200190565b941515855264ffffffffff93841660208601526001600160d01b0392831660408601529216606084015216608082015260a00190565b6000602082528251806020840152614578816040850160208701614c0d565b601f01601f19169190910160400192915050565b602080825260159082015274426f72696e674d6174683a20556e646572666c6f7760581b604082015260600190565b6020808252601c908201527f426f72696e674d6174683a2075696e74323038204f766572666c6f7700000000604082015260600190565b6020808252601c908201527f426f72696e674d6174683a206469766973696f6e206279207a65726f00000000604082015260600190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252600e908201526d043616e6e6f74207374616b6520360941b604082015260600190565b6020808252600e908201526d1bdd995c881b585e081cdc195b9960921b604082015260600190565b60208082526010908201526f1bdd995c881b585e081c185e5b595b9d60821b604082015260600190565b6020808252600d908201526c6f766572206d6178207261746560981b604082015260600190565b6020808252600c908201526b6e6f20657870206c6f636b7360a01b604082015260600190565b6020808252600f908201526e696e76616c6964206164647265737360881b604082015260600190565b60208082526018908201527f426f72696e674d6174683a20416464204f766572666c6f770000000000000000604082015260600190565b6020808252601c908201527f426f72696e674d6174683a2075696e74313132204f766572666c6f7700000000604082015260600190565b602080825260099082015268139bc81c995dd85c9960ba1b604082015260600190565b60208082526007908201526610b0b9b9b4b3b760c91b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601d908201527f43616e6e6f74207769746864726177207374616b696e6720746f6b656e000000604082015260600190565b6020808252600990820152686d696e2064656c617960b81b604082015260600190565b60208082526008908201526739b43aba3237bbb760c11b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252600990820152686d696e2072616e676560b81b604082015260600190565b6020808252601b908201527f426f72696e674d6174683a2075696e743332204f766572666c6f770000000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252601c908201527f43616e6e6f742077697468647261772072657761726420746f6b656e00000000604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252600990820152686d61782072616e676560b81b604082015260600190565b60208082526036908201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60408201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606082015260800190565b60208082526018908201527f426f72696e674d6174683a204d756c204f766572666c6f770000000000000000604082015260600190565b6020808252601b908201527f426f72696e674d6174683a2075696e743430204f766572666c6f770000000000604082015260600190565b6001600160701b039290921682521515602082015260400190565b6001600160701b03938416815291909216602082015263ffffffff909116604082015260600190565b6001600160e01b0392909216825263ffffffff16602082015260400190565b90815260200190565b9283526001600160701b03918216602084015216604082015260600190565b6000608082018683526020868185015260408681860152606060808187015283875180865260a0880191508489019550865b81811015614bee57865180516001600160701b03908116855287820151168785015285015163ffffffff16858401529585019591830191600101614baf565b50909b9a5050505050505050505050565b60ff91909116815260200190565b60005b83811015614c28578181015183820152602001614c10565b838111156135f05750506000910152565b6001600160a01b0381168114611e9f57600080fd5b8015158114611e9f57600080fdfea26469706673582212200daca5079d08a2a2879895b2312c0d991308583c3b5872c6c0d929844700353664736f6c634300060c0033
Deployed Bytecode Sourcemap
36474:35136:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37855:59;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;52507:961;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;:::i;39973:83::-;;;:::i;:::-;;;;;;;:::i;50221:777::-;;;:::i;47612:1085::-;;;;;;:::i;:::-;;:::i;38961:27::-;;;:::i;:::-;;;;;;;:::i;38421:44::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;38679:32::-;;;:::i;45888:126::-;;;;;;:::i;:::-;;:::i;64782:155::-;;;;;;:::i;:::-;;:::i;:::-;;39884:83;;;:::i;:::-;;;;;;;:::i;37748:51::-;;;:::i;37989:70::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;37647:44::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;:::i;40155:74::-;;;:::i;46109:126::-;;;;;;:::i;:::-;;:::i;44606:177::-;;;;;;:::i;:::-;;:::i;42475:301::-;;;;;;:::i;:::-;;:::i;39093:47::-;;;:::i;41005:290::-;;;;;;:::i;:::-;;:::i;48759:535::-;;;;;;:::i;:::-;;:::i;38107:77::-;;;;;;:::i;:::-;;:::i;67222:709::-;;;;;;:::i;:::-;;:::i;46360:1145::-;;;;;;:::i;:::-;;:::i;51079:606::-;;;;;;:::i;:::-;;:::i;32388:148::-;;;:::i;37402:88::-;;;:::i;38323:28::-;;;:::i;37611:29::-;;;;;;:::i;:::-;;:::i;38718:42::-;;;:::i;37503:84::-;;;:::i;53500:92::-;;;:::i;43180:293::-;;;:::i;64945:257::-;;;;;;:::i;:::-;;:::i;69634:404::-;;;;;;:::i;:::-;;:::i;41619:350::-;;;;;;:::i;:::-;;:::i;31737:87::-;;;:::i;40062:::-;;;:::i;38810:43::-;;;:::i;39217:39::-;;;:::i;41358:166::-;;;;;;:::i;:::-;;:::i;42005:436::-;;;;;;:::i;:::-;;:::i;38546:81::-;;;:::i;38472:52::-;;;;;;:::i;:::-;;:::i;38995:91::-;;;:::i;38634:38::-;;;:::i;38919:35::-;;;:::i;38767:36::-;;;:::i;68795:724::-;;;;;;:::i;:::-;;:::i;44933:176::-;;;;;;:::i;:::-;;:::i;39327:30::-;;;:::i;67973:89::-;;;;;;:::i;:::-;;:::i;53654:73::-;;;:::i;38358:21::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;38289:27::-;;;:::i;49302:827::-;;;;;;:::i;:::-;;:::i;64525:164::-;;;;;;:::i;:::-;;:::i;40352:579::-;;;;;;:::i;:::-;;:::i;45197:594::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;55009:297::-;;;;;;:::i;:::-;;:::i;39263:39::-;;;:::i;38191:62::-;;;;;;:::i;:::-;;:::i;38877:35::-;;;:::i;44791:134::-;;;;;;:::i;:::-;;:::i;32691:244::-;;;;;;:::i;:::-;;:::i;51739:710::-;;;;;;:::i;:::-;;:::i;42852:272::-;;;:::i;37855:59::-;37894:20;37855:59;:::o;52507:961::-;-1:-1:-1;;;;;52754:16:0;;52594:13;52754:16;;;:9;:16;;;;;;;;52812:8;:15;;;;;52864:27;;52594:13;;;;52672:31;;-1:-1:-1;;;52864:27:0;;;;52594:13;52864:27;52924:469;52959:12;;52955:16;;52924:469;;;53019:15;52997:5;53003:1;52997:8;;;;;;;;;;;;;;;;;:19;-1:-1:-1;;;52997:19:0;;;;:37;52993:389;;;53059:8;53055:105;;53123:12;;:16;;;53103:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;53092:48;;53055:105;53194:5;53200:1;53194:8;;;;;;;;;;;;;;;;;53178:24;;;;;;;;53194:8;;;;53178:24;-1:-1:-1;;;;;53178:24:0;;;;;-1:-1:-1;;;53178:24:0;;;;;;;;;;;-1:-1:-1;;;53178:24:0;;;;;;;;;;;:13;;:8;;53187:3;;53178:13;;;;;;;;;;;:24;;;;53221:5;;;;;;;53254:27;53265:5;53271:1;53265:8;;;;;;;;;;;;;;;;;:15;53254:6;;-1:-1:-1;;;;;53265:15:0;53254:10;:27::i;:::-;53245:36;;52993:389;;;53335:31;53350:5;53356:1;53350:8;;;;;;;;;;;;;;;;;:15;53335:10;;-1:-1:-1;;;;;53350:15:0;53335:14;:31::i;:::-;53322:44;;52993:389;52973:3;;52924:469;;;-1:-1:-1;;53411:18:0;;-1:-1:-1;;;;;53411:18:0;;-1:-1:-1;;;52507:961:0;;;;;:::o;39973:83::-;40043:5;40036:12;;;;;;;;-1:-1:-1;;40036:12:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40010:13;;40036:12;;40043:5;;40036:12;;40043:5;40036:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39973:83;:::o;50221:777::-;50266:14;;50318:57;37790:9;50318:36;:15;37790:9;50318:19;:36::i;:::-;:40;;:57::i;:::-;50295:80;-1:-1:-1;50386:19:0;50408:30;50295:80;37894:20;50408:16;:30::i;:::-;50470:6;:13;;50386:52;;-1:-1:-1;50586:12:0;;-1:-1:-1;;50562:14:0;;50555:22;;;;;;;;;;;;;;;;:27;-1:-1:-1;;;50555:27:0;;;;50547:51;50542:98;;;-1:-1:-1;;50616:12:0;50542:98;-1:-1:-1;;50744:14:0;;50730:235;50764:1;50760:5;;:10;50730:235;;50792:15;50810:6;50817:1;50810:9;;;;;;;;;;;;;;;;;50846:6;;50810:9;;-1:-1:-1;;;;50846:6:0;;;;-1:-1:-1;;50834:76:0;;50889:5;;;50834:76;50944:8;;50933:20;;:6;;-1:-1:-1;;;;;50944:8:0;50933:10;:20::i;:::-;50924:29;-1:-1:-1;;;;50772:3:0;50730:235;;;;50977:13;;;50221:777;:::o;47612:1085::-;-1:-1:-1;;;;;47750:16:0;;47691:14;47750:16;;;:9;:16;;;;;47845:6;:14;;47691;;47845:6;47852;;47845:14;;;;;;;;;;;;;;:19;;-1:-1:-1;;;47845:19:0;;;;;;-1:-1:-1;47951:27:0;;47845:19;;37894:20;;47951:13;:27;:::i;:::-;48158:12;;47929:49;;-1:-1:-1;;;48158:16:0;48144:520;48180:1;48176:5;;:10;48144:520;;48208:17;48228:46;37790:9;37912:2;37894:20;48236:5;48242:1;48236:8;;;;;;;;;;;;;;;;;:19;;-1:-1:-1;;;48236:19:0;;;;;;48228:46;:32;:46;:::i;:::-;48208:66;;48386:9;48373;:22;48369:284;;48432:11;48420:9;:23;48416:222;;;48477:28;48488:5;48494:1;48488:8;;;;;;;;;;;;;;;;;:16;48477:6;;-1:-1:-1;;;48488:16:0;;-1:-1:-1;;;;;48488:16:0;48477:10;:28::i;:::-;48468:37;;48416:222;;;48613:5;;;48416:222;-1:-1:-1;;;48188:3:0;48144:520;;;;48676:13;;;47612:1085;;;;;:::o;38961:27::-;;;-1:-1:-1;;;;;38961:27:0;;:::o;38421:44::-;;;;;;;;;;;;-1:-1:-1;;;;;38421:44:0;;;;-1:-1:-1;;;38421:44:0;;;;;;-1:-1:-1;;;38421:44:0;;;;;:::o;38679:32::-;;;;:::o;45888:126::-;-1:-1:-1;;;;;45983:15:0;;45949:14;45983:15;;;:8;:15;;;;;:23;-1:-1:-1;;;45983:23:0;;-1:-1:-1;;;;;45983:23:0;45888:126;;;;:::o;64782:155::-;34690:1;35296:7;;:19;;35288:63;;;;-1:-1:-1;;;35288:63:0;;;;;;;:::i;:::-;;;;;;;;;34690:1;35429:7;:18;;;;64858:71:::1;64879:10;64891:7;64900:1;64903:10;64915;64927:1;64858:20;:71::i;:::-;-1:-1:-1::0;34646:1:0;35608:7;:22;64782:155::o;39884:83::-;39950:9;39884:83;:::o;37748:51::-;37790:9;37748:51;:::o;37989:70::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;37647:44::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;37647:44:0;;;;;;;;;;-1:-1:-1;;;37647:44:0;;;;;:::o;40155:74::-;40220:1;40155:74;:::o;46109:126::-;-1:-1:-1;;;;;46205:15:0;46171:14;46205:15;;;:8;:15;;;;;:22;-1:-1:-1;;;;;46205:22:0;;46109:126::o;44606:177::-;-1:-1:-1;;;;;44736:25:0;;44683:7;44736:25;;;:10;:25;;;;;:38;44710:65;;44736:38;;;;;44710:25;:65::i;42475:301::-;31968:12;:10;:12::i;:::-;-1:-1:-1;;;;;31957:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;31957:23:0;;31949:68;;;;-1:-1:-1;;;31949:68:0;;;;;;;:::i;:::-;42579:3:::1;42570:5;:12;;42562:38;;;;-1:-1:-1::0;;;42562:38:0::1;;;;;;;:::i;:::-;42648:1;42638:6;:11;;42630:33;;;;-1:-1:-1::0;;;42630:33:0::1;;;;;;;:::i;:::-;42702:18;:26:::0;;;;42739:20:::1;:29:::0;42475:301::o;39093:47::-;39137:3;39093:47;:::o;41005:290::-;31968:12;:10;:12::i;:::-;-1:-1:-1;;;;;31957:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;31957:23:0;;31949:68;;;;-1:-1:-1;;;31949:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;41172:25:0;::::1;41215:1;41172:25:::0;;;:10:::1;:25;::::0;;;;:40:::1;;::::0;::::1;;41164:53;;;::::0;::::1;;-1:-1:-1::0;;;;;41228:33:0;;::::1;;::::0;;;:18:::1;:33;::::0;;;;;;;:47;;;::::1;::::0;;;;;;;;;:59;;-1:-1:-1;;41228:59:0::1;::::0;::::1;;::::0;;;::::1;::::0;;41005:290::o;48759:535::-;-1:-1:-1;;;;;48878:16:0;;48819:14;48878:16;;;:9;:16;;;;;48929:12;;48819:14;49034:57;37790:9;49034:36;:15;37790:9;49034:19;:36::i;:57::-;49011:80;;49120:1;49106:11;:15;:94;;;;;49188:12;49125:60;37790:9;37912:2;37894:20;49133:5;49153:1;49139:11;:15;49133:22;;;;;;;49125:60;:75;49106:94;49102:164;;;49224:5;49244:1;49230:11;:15;49224:22;;;;;;;;;;;;;;;;;:30;-1:-1:-1;;;49224:30:0;;-1:-1:-1;;;;;49224:30:0;;-1:-1:-1;49217:37:0;;-1:-1:-1;;;49217:37:0;49102:164;-1:-1:-1;49285:1:0;;48759:535;-1:-1:-1;;;;48759:535:0:o;38107:77::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;67222:709::-;34690:1;35296:7;;:19;;35288:63;;;;-1:-1:-1;;;35288:63:0;;;;;;;:::i;:::-;34690:1;35429:7;:18;;;-1:-1:-1;;;;;70204:18:0;::::1;::::0;;:8:::1;:18;::::0;;;;70258:19;;70204:18;;-1:-1:-1;;;70258:19:0;;::::1;-1:-1:-1::0;;;;;70258:19:0::1;::::0;70292:729:::1;70313:12;:19:::0;70309:23;::::1;70292:729;;;70358:13;70374:12;70387:1;70374:15;;;;;;;;;::::0;;;::::1;::::0;;;::::1;::::0;-1:-1:-1;;;;;70374:15:0::1;::::0;-1:-1:-1;70449:30:0::1;:22;70374:15:::0;70449::::1;:22::i;:::-;:28;:30::i;:::-;-1:-1:-1::0;;;;;70408:17:0;::::1;;::::0;;;:10:::1;:17;::::0;;;;:38:::1;::::0;::::1;:71:::0;;-1:-1:-1;;;;;70408:71:0;;;::::1;-1:-1:-1::0;;;70408:71:0::1;-1:-1:-1::0;;;;;;;;70408:71:0;;::::1;::::0;;;::::1;::::0;;;70559:30;70533:64:::1;::::0;:57:::1;::::0;70559:30:::1;70408:71;70559:30:::0;;::::1;;70533:25;:57::i;:::-;:62;:64::i;:::-;-1:-1:-1::0;;;;;70498:17:0;;::::1;;::::0;;;:10:::1;:17;::::0;;;;:32:::1;;:99:::0;;-1:-1:-1;;70498:99:0::1;;::::0;;;::::1;::::0;;;::::1;::::0;;;70620:22;::::1;::::0;70616:390:::1;;-1:-1:-1::0;;;;;70821:17:0;::::1;;::::0;;;:10:::1;:17;::::0;;;;:26;70796:87:::1;::::0;70804:8;;70814:5;;70821:26:::1;;:60;;70863:18:::0;;-1:-1:-1;;;;;70863:18:0::1;70821:60;;;70850:10;70821:60;70796:7;:87::i;:::-;-1:-1:-1::0;;;;;70769:17:0;;::::1;;::::0;;;:7:::1;:17;::::0;;;;;;;:24;;::::1;::::0;;;;;;;;;:114;;;;70948:10:::1;:17:::0;;;;;:38:::1;;::::0;70906:32;;;70948:38:::1;70906:32:::0;;;;;:39;;;;;;;;;;-1:-1:-1;;;70948:38:0;;::::1;-1:-1:-1::0;;;;;70948:38:0::1;70906:80:::0;;70616:390:::1;-1:-1:-1::0;70334:3:0::1;;70292:729;;;;35460:1;;67331:6:::2;67326:598;67343:12;:19:::0;67339:23;::::2;67326:598;;;67384:21;67408:12;67421:1;67408:15;;;;;;;;;::::0;;;::::2;::::0;;;;;::::2;::::0;-1:-1:-1;;;;;67455:17:0;;::::2;::::0;;:7:::2;:17:::0;;;;;;67408:15;;;::::2;67455:32:::0;;;;;;;;;67408:15;;-1:-1:-1;67506:10:0;;67502:411:::2;;-1:-1:-1::0;;;;;67537:17:0;;::::2;67572:1;67537:17:::0;;;:7:::2;:17;::::0;;;;;;;:32;;::::2;::::0;;;;;;;;;:36;37544:42:::2;67596:23;:33:::0;::::2;;;;67623:6;67596:33;67592:239;;;67654:56;::::0;-1:-1:-1;;;67654:56:0;;39043:42:::2;::::0;67654:38:::2;::::0;:56:::2;::::0;67693:8;;67703:6;;67654:56:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;67592:239;;;67759:52;-1:-1:-1::0;;;;;67759:34:0;::::2;67794:8:::0;67804:6;67759:34:::2;:52::i;:::-;67875:13;-1:-1:-1::0;;;;;67854:43:0::2;67865:8;-1:-1:-1::0;;;;;67854:43:0::2;;67890:6;67854:43;;;;;;:::i;:::-;;;;;;;;67502:411;-1:-1:-1::0;;67364:3:0::2;;67326:598;;;-1:-1:-1::0;;34646:1:0;35608:7;:22;-1:-1:-1;;67222:709:0:o;46360:1145::-;-1:-1:-1;;;;;46475:16:0;;46416:14;46475:16;;;:9;:16;;;;;;;;46533:8;:15;;;;;;46585:27;;46737:12;;-1:-1:-1;;;46679:23:0;;-1:-1:-1;;;;;46679:23:0;;46475:16;46533:15;-1:-1:-1;;;46585:27:0;;;;;;46836:300;46871:11;46867:1;:15;46836:300;;;46931:15;46908:5;46914:1;46908:8;;;;;;;;;;;;;;;;;:19;-1:-1:-1;;;46908:19:0;;;;:38;46904:221;;46976:28;46987:5;46993:1;46987:8;;;;;;;;;;;;;;;;;:16;46976:6;;-1:-1:-1;;;46987:16:0;;-1:-1:-1;;;;;46987:16:0;46976:10;:28::i;:::-;46967:37;;46904:221;;;47104:5;;46904:221;46884:3;;46836:300;;;-1:-1:-1;47203:20:0;47226:57;37790:9;47226:36;:15;37790:9;47226:19;:36::i;:57::-;47203:80;;47312:1;47298:11;:15;:94;;;;;47380:12;47317:60;37790:9;37912:2;37894:20;47325:5;47345:1;47331:11;:15;47325:22;;;;;;;47317:60;:75;47298:94;47294:178;;;47418:42;47429:5;47449:1;47435:11;:15;47429:22;;;;;;;47418:42;47409:51;;47294:178;47484:13;;;;;46360:1145;;;:::o;51079:606::-;51145:14;51174:18;51195:70;37790:9;51195:49;37790:9;51203:6;51210;51203:14;;;;;;;;;;;;;;;;;:19;;-1:-1:-1;;;51203:19:0;;;;;;51195:49;:32;:49;:::i;:70::-;51174:91;-1:-1:-1;51276:19:0;51298:28;51174:91;37894:20;51298:14;:28::i;:::-;51276:50;-1:-1:-1;51431:6:0;51417:235;51443:1;51439:5;;:10;51417:235;;51471:15;51489:6;51496:1;51489:9;;;;;;;;;;;;;;;;;51525:6;;51489:9;;-1:-1:-1;;;;51525:6:0;;;;-1:-1:-1;;51513:76:0;;51568:5;;;51513:76;51612:28;51623:6;51630:1;51623:9;;;;;;;;;;;;;;;;;:16;51612:6;;-1:-1:-1;;;;;51623:16:0;51612:10;:28::i;:::-;51603:37;-1:-1:-1;;;;51451:3:0;51417:235;;;;51664:13;;51079:606;;;:::o;32388:148::-;31968:12;:10;:12::i;:::-;-1:-1:-1;;;;;31957:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;31957:23:0;;31949:68;;;;-1:-1:-1;;;31949:68:0;;;;;;;:::i;:::-;32479:6:::1;::::0;32458:40:::1;::::0;32495:1:::1;::::0;-1:-1:-1;;;;;32479:6:0::1;::::0;32458:40:::1;::::0;32495:1;;32458:40:::1;32509:6;:19:::0;;-1:-1:-1;;;;;;32509:19:0::1;::::0;;32388:148::o;37402:88::-;37447:42;37402:88;:::o;38323:28::-;;;;:::o;37611:29::-;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;37611:29:0;;-1:-1:-1;37611:29:0;:::o;38718:42::-;;;;:::o;37503:84::-;37544:42;37503:84;:::o;53500:92::-;53571:6;:13;53500:92;:::o;43180:293::-;43224:44;37544:42;39043;43266:1;43224:26;:44::i;:::-;43279:54;37544:42;39043;-1:-1:-1;;43279:26:0;:54::i;:::-;43379:12;;43346:49;;37447:42;;-1:-1:-1;;;;;43379:12:0;;43346:32;:49::i;:::-;43439:12;;43406:59;;37447:42;;-1:-1:-1;;;;;43439:12:0;-1:-1:-1;;43406:32:0;:59::i;:::-;43180:293::o;64945:257::-;34690:1;35296:7;;:19;;35288:63;;;;-1:-1:-1;;;35288:63:0;;;;;;;:::i;:::-;34690:1;35429:7;:18;;;;65089:105:::1;65110:8;65120:5;65127:1:::0;65130:8:::1;65140:10;65152:41;65172:20;;37790:9;65152:19;;:41;;;;:::i;:::-;65089:20;:105::i;69634:404::-:0;31968:12;:10;:12::i;:::-;-1:-1:-1;;;;;31957:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;31957:23:0;;31949:68;;;;-1:-1:-1;;;31949:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;69739:38:0;::::1;37447:42;69739:38;;69731:80;;;;-1:-1:-1::0;;;69731:80:0::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;69830:25:0;::::1;;::::0;;;:10:::1;:25;::::0;;;;:40:::1;;::::0;::::1;;:45:::0;69822:86:::1;;;;-1:-1:-1::0;;;69822:86:0::1;;;;;;;:::i;:::-;69919:57;69954:7;:5;:7::i;:::-;-1:-1:-1::0;;;;;69919:34:0;::::1;::::0;69963:12;69919:34:::1;:57::i;:::-;69992:38;70002:13;70017:12;69992:38;;;;;;;:::i;:::-;;;;;;;;69634:404:::0;;:::o;41619:350::-;31968:12;:10;:12::i;:::-;-1:-1:-1;;;;;31957:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;31957:23:0;;31949:68;;;;-1:-1:-1;;;31949:68:0;;;;;;;:::i;:::-;38848:5:::1;41717:8;:23;;41709:45;;;;-1:-1:-1::0;;;41709:45:0::1;;;;;;;:::i;:::-;38848:5;41773:8;:23;;41765:45;;;;-1:-1:-1::0;;;41765:45:0::1;;;;;;;:::i;:::-;41841:8;41829;:20;;41821:42;;;;-1:-1:-1::0;;;41821:42:0::1;;;;;;;:::i;:::-;41874:12;:23:::0;;;41908:12:::1;:23:::0;;;41942:19:::1;-1:-1:-1::0;41942:16:0::1;:19::i;:::-;41619:350:::0;;:::o;31737:87::-;31810:6;;-1:-1:-1;;;;;31810:6:0;31737:87;:::o;40062:::-;40134:7;40127:14;;;;;;;;-1:-1:-1;;40127:14:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40101:13;;40127:14;;40134:7;;40127:14;;40134:7;40127:14;;;;;;;;;;;;;;;;;;;;;;;;38810:43;38848:5;38810:43;:::o;39217:39::-;;;;:::o;41358:166::-;31968:12;:10;:12::i;:::-;-1:-1:-1;;;;;31957:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;31957:23:0;;31949:68;;;;-1:-1:-1;;;31949:68:0;;;;;;;:::i;:::-;41442:12:::1;::::0;-1:-1:-1;;;;;41442:12:0::1;:26:::0;41434:46:::1;;;;-1:-1:-1::0;;;41434:46:0::1;;;;;;;:::i;:::-;41493:12;:23:::0;;-1:-1:-1;;;;;;41493:23:0::1;-1:-1:-1::0;;;;;41493:23:0;;;::::1;::::0;;;::::1;::::0;;41358:166::o;42005:436::-;31968:12;:10;:12::i;:::-;-1:-1:-1;;;;;31957:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;31957:23:0;;31949:68;;;;-1:-1:-1;;;31949:68:0;;;;;;;:::i;:::-;42124:4:::1;42117;:11;42109:40;;;;-1:-1:-1::0;;;42109:40:0::1;;;;;;;:::i;:::-;42186:5;42178;:13;42170:39;;;;-1:-1:-1::0;;;42170:39:0::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;42237:31:0;::::1;42229:59;;;;-1:-1:-1::0;;;42229:59:0::1;;;;;;;:::i;:::-;42328:23;:30:::0;;;;42369:13:::1;:21:::0;42401:12:::1;:32:::0;;-1:-1:-1;;;;;;42401:32:0::1;-1:-1:-1::0;;;;;42401:32:0;;::::1;::::0;;;::::1;::::0;;42005:436::o;38546:81::-;;;-1:-1:-1;;;;;38546:81:0;;:::o;38472:52::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;38472:52:0;;;;-1:-1:-1;;;;38472:52:0;;;;-1:-1:-1;;;;38472:52:0;;;;;:::o;38995:91::-;39043:42;38995:91;:::o;38634:38::-;;;;:::o;38919:35::-;;;;:::o;38767:36::-;;;;:::o;68795:724::-;68893:1;70204:18;;;:8;:18;;;70258:19;;-1:-1:-1;;;70258:19:0;;-1:-1:-1;;;;;70258:19:0;68893:1;70292:729;70313:12;:19;70309:23;;70292:729;;;70358:13;70374:12;70387:1;70374:15;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;70374:15:0;;-1:-1:-1;70449:30:0;:22;70374:15;70449;:22::i;:30::-;-1:-1:-1;;;;;70408:17:0;;;;;;:10;:17;;;;;:38;;;:71;;-1:-1:-1;;;;;70408:71:0;;;;-1:-1:-1;;;70408:71:0;-1:-1:-1;;;;;;;;70408:71:0;;;;;;;;;;70559:30;70533:64;;:57;;70559:30;70408:71;70559:30;;;;70533:25;:57::i;:64::-;-1:-1:-1;;;;;70498:17:0;;;;;;;:10;:17;;;;;:32;;:99;;-1:-1:-1;;70498:99:0;;;;;;;;;;;;;70620:22;;;70616:390;;-1:-1:-1;;;;;70821:17:0;;;;;;:10;:17;;;;;:26;70796:87;;70804:8;;70814:5;;70821:26;;:60;;70863:18;;-1:-1:-1;;;;;70863:18:0;70821:60;;70796:87;-1:-1:-1;;;;;70769:17:0;;;;;;;:7;:17;;;;;;;;:24;;;;;;;;;;;;:114;;;;70948:10;:17;;;;;:38;;;70906:32;;;70948:38;70906:32;;;;;:39;;;;;;;;;;-1:-1:-1;;;70948:38:0;;;-1:-1:-1;;;;;70948:38:0;70906:80;;70616:390;-1:-1:-1;70334:3:0;;70292:729;;;-1:-1:-1;;;;;;;;68916:33:0;::::1;;::::0;;;:18:::1;:33;::::0;;;;;;;68950:10:::1;68916:45:::0;;;;;;;;::::1;;68908:54;;;::::0;::::1;;68991:1;68981:7;:11;68973:33;;;;-1:-1:-1::0;;;68973:33:0::1;;;;;;;:::i;:::-;69019:37;69033:13;69048:7;69019:13;:37::i;:::-;69240:74;-1:-1:-1::0;;;;;69240:38:0;::::1;69279:10;69299:4;69306:7:::0;69240:38:::1;:74::i;:::-;69352:13;-1:-1:-1::0;;;;;69340:35:0::1;;69367:7;69340:35;;;;;;:::i;:::-;;;;;;;;-1:-1:-1::0;;;;;69391:23:0;::::1;37544:42;69391:23;69388:124;;;69481:19;69498:1;69481:16;:19::i;:::-;68795:724:::0;;;:::o;44933:176::-;-1:-1:-1;;;;;45043:25:0;;45008:7;45043:25;;;:10;:25;;;;;:36;45035:66;;-1:-1:-1;;;45043:36:0;;-1:-1:-1;;;;;45043:36:0;37790:9;45035:49;:66::i;39327:30::-;;;;;;:::o;67973:89::-;68029:25;68039:8;68048:5;68029:9;:25::i;:::-;67973:89;:::o;53654:73::-;53701:18;:16;:18::i;38358:21::-;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;38358:21:0;;;-1:-1:-1;;;;38358:21:0;;;;;:::o;38289:27::-;;;;:::o;49302:827::-;-1:-1:-1;;;;;49444:16:0;;49385:14;49444:16;;;:9;:16;;;;;49554:6;:14;;49385;;49546:49;;37790:9;;49554:6;49561;;49554:14;;;;;;;;;;;;;;;:19;;-1:-1:-1;;;49554:19:0;;;;;;49546:49;:32;:49;:::i;:::-;49700:12;;49526:69;;-1:-1:-1;;;49700:16:0;49686:415;49722:1;49718:5;;:10;49686:415;;49750:17;49770:46;37790:9;37912:2;37894:20;49778:5;49784:1;49778:8;;;;;;;49770:46;49750:66;;49907:9;49894;:22;49890:200;;;49944:5;49950:1;49944:8;;;;;;;;;;;;;;;;;:16;-1:-1:-1;;;49944:16:0;;-1:-1:-1;;;;;49944:16:0;;-1:-1:-1;49937:23:0;;-1:-1:-1;;;;49937:23:0;49890:200;49996:9;49984;:21;49981:109;;;50069:5;;;49981:109;-1:-1:-1;;;49730:3:0;49686:415;;;-1:-1:-1;50120:1:0;;49302:827;-1:-1:-1;;;;;49302:827:0:o;64525:164::-;34690:1;35296:7;;:19;;35288:63;;;;-1:-1:-1;;;35288:63:0;;;;;;;:::i;:::-;34690:1;35429:7;:18;;;;64611:70:::1;64632:10;64644:5;64651:1:::0;64654:11:::1;64667:10;64679:1;64611:20;:70::i;40352:579::-:0;31968:12;:10;:12::i;:::-;-1:-1:-1;;;;;31957:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;31957:23:0;;31949:68;;;;-1:-1:-1;;;31949:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;40502:25:0;::::1;;::::0;;;:10:::1;:25;::::0;;;;:40:::1;;::::0;::::1;;:45:::0;40494:54:::1;;;::::0;::::1;;-1:-1:-1::0;;;;;40567:38:0;::::1;37447:42;40567:38;;40559:47;;;::::0;::::1;;40617:12;:32:::0;;::::1;::::0;;::::1;::::0;;;;::::1;::::0;;-1:-1:-1;;;;;;40617:32:0::1;-1:-1:-1::0;;;;;40617:32:0;;::::1;::::0;;::::1;::::0;;;-1:-1:-1;40660:25:0;;;:10:::1;40617:32;40660:25:::0;;;;;;;:40;;::::1;:66:::0;;-1:-1:-1;;40660:66:0::1;40710:15;40660:66;;::::0;;::::1;::::0;;;40737:64;;-1:-1:-1;;40737:64:0::1;40617:32;40737:64:::0;;::::1;;-1:-1:-1::0;;40812:46:0;;::::1;::::0;::::1;;::::0;;;::::1;::::0;;40869:18:::1;:33:::0;;;;;:47;;;::::1;::::0;;;;;;;;;;:54;;;;::::1;::::0;;::::1;::::0;;40352:579::o;45197:594::-;45338:12;:19;45263:31;;45321:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;45400:18:0;;45369:28;45400:18;;;:8;:18;;;;;45450:19;;45307:51;;-1:-1:-1;45400:18:0;-1:-1:-1;;;45450:19:0;;-1:-1:-1;;;;;45450:19:0;;45480:275;45504:11;:18;45500:1;:22;45480:275;;;45544:13;45560:12;45573:1;45560:15;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;45560:15:0;45544:31;;45613:5;45590:11;45602:1;45590:14;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;45590:28:0;;;;;45682:17;;;45590:20;45682:17;;;:10;:17;;;;;;:26;45657:86;;45665:8;;45675:5;;45682:26;;:60;;45724:18;;-1:-1:-1;;;;;45724:18:0;45682:60;;45657:86;45633:11;45645:1;45633:14;;;;;;;;;;;;;;;;;;;:21;:110;-1:-1:-1;45524:3:0;;45480:275;;55009:297;34690:1;35296:7;;:19;;35288:63;;;;-1:-1:-1;;;35288:63:0;;;;;;;:::i;:::-;34690:1;35429:7;:18;;;-1:-1:-1;;;;;70204:18:0;::::1;::::0;;:8:::1;:18;::::0;;;;70258:19;;70204:18;;-1:-1:-1;;;70258:19:0;;::::1;-1:-1:-1::0;;;;;70258:19:0::1;::::0;70292:729:::1;70313:12;:19:::0;70309:23;::::1;70292:729;;;70358:13;70374:12;70387:1;70374:15;;;;;;;;;::::0;;;::::1;::::0;;;::::1;::::0;-1:-1:-1;;;;;70374:15:0::1;::::0;-1:-1:-1;70449:30:0::1;:22;70374:15:::0;70449::::1;:22::i;:30::-;-1:-1:-1::0;;;;;70408:17:0;::::1;;::::0;;;:10:::1;:17;::::0;;;;:38:::1;::::0;::::1;:71:::0;;-1:-1:-1;;;;;70408:71:0;;;::::1;-1:-1:-1::0;;;70408:71:0::1;-1:-1:-1::0;;;;;;;;70408:71:0;;::::1;::::0;;;::::1;::::0;;;70559:30;70533:64:::1;::::0;:57:::1;::::0;70559:30:::1;70408:71;70559:30:::0;;::::1;;70533:25;:57::i;:64::-;-1:-1:-1::0;;;;;70498:17:0;;::::1;;::::0;;;:10:::1;:17;::::0;;;;:32:::1;;:99:::0;;-1:-1:-1;;70498:99:0::1;;::::0;;;::::1;::::0;;;::::1;::::0;;;70620:22;::::1;::::0;70616:390:::1;;-1:-1:-1::0;;;;;70821:17:0;::::1;;::::0;;;:10:::1;:17;::::0;;;;:26;70796:87:::1;::::0;70804:8;;70814:5;;70821:26:::1;;:60;;70863:18:::0;;-1:-1:-1;;;;;70863:18:0::1;70821:60;;70796:87;-1:-1:-1::0;;;;;70769:17:0;;::::1;;::::0;;;:7:::1;:17;::::0;;;;;;;:24;;::::1;::::0;;;;;;;;;:114;;;;70948:10:::1;:17:::0;;;;;:38:::1;;::::0;70906:32;;;70948:38:::1;70906:32:::0;;;;;:39;;;;;;;;;;-1:-1:-1;;;70948:38:0;;::::1;-1:-1:-1::0;;;;;70948:38:0::1;70906:80:::0;;70616:390:::1;-1:-1:-1::0;70334:3:0::1;;70292:729;;;-1:-1:-1::0;55160:65:0::2;::::0;-1:-1:-1;37447:42:0::2;::::0;-1:-1:-1;55190:10:0::2;55210:4;55217:7:::0;55160:29:::2;:65::i;:::-;55254:44;55260:8;55270:7;55279:11;55292:5;55254;:44::i;39263:39::-:0;;;;:::o;38191:62::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;38877:35::-;;;;:::o;44791:134::-;44860:7;44887:30;44903:13;44887:15;:30::i;32691:244::-;31968:12;:10;:12::i;:::-;-1:-1:-1;;;;;31957:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;31957:23:0;;31949:68;;;;-1:-1:-1;;;31949:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;32780:22:0;::::1;32772:73;;;;-1:-1:-1::0;;;32772:73:0::1;;;;;;;:::i;:::-;32882:6;::::0;32861:38:::1;::::0;-1:-1:-1;;;;;32861:38:0;;::::1;::::0;32882:6:::1;::::0;32861:38:::1;::::0;32882:6:::1;::::0;32861:38:::1;32910:6;:17:::0;;-1:-1:-1;;;;;;32910:17:0::1;-1:-1:-1::0;;;;;32910:17:0;;;::::1;::::0;;;::::1;::::0;;32691:244::o;51739:710::-;51837:6;:13;51797;;-1:-1:-1;;51837:17:0;51797:13;51935:47;37790:9;51935:26;:5;37790:9;51935;:26::i;:47::-;51927:55;;52000:9;51995:426;52019:3;52015:1;:7;51995:426;;;52055:3;52048;:10;52044:21;;52060:5;;52044:21;52082:11;52114:1;52109;52097:9;;;:13;52096:19;52082:33;;52130:21;52154:6;52161:3;52154:11;;;;;;;;;;;;;;;;;:16;-1:-1:-1;;;52154:16:0;;;;;-1:-1:-1;52188:22:0;;;52185:225;;;-1:-1:-1;52262:3:0;-1:-1:-1;52255:10:0;;-1:-1:-1;;;52255:10:0;52185:225;52306:5;52290:13;:21;52286:124;;;52338:3;52332:9;;52286:124;;;52393:1;52387:3;:7;52381:13;;52286:124;-1:-1:-1;;52024:3:0;;51995:426;;;-1:-1:-1;52438:3:0;51739:710;-1:-1:-1;;;51739:710:0:o;42852:272::-;31968:12;:10;:12::i;:::-;-1:-1:-1;;;;;31957:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;31957:23:0;;31949:68;;;;-1:-1:-1;;;31949:68:0;;;;;;;:::i;:::-;42906:12:::1;::::0;-1:-1:-1;;;;;42906:12:0::1;:26:::0;42902:187:::1;;42986:12;::::0;42972:40:::1;::::0;;-1:-1:-1;;;42972:40:0;;;;42949:20:::1;::::0;-1:-1:-1;;;;;42986:12:0::1;::::0;42972:38:::1;::::0;:40:::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;42986:12;42972:40;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;43041:12;::::0;43027:50:::1;::::0;-1:-1:-1;;;43027:50:0;;42949:63;;-1:-1:-1;;;;;;43041:12:0::1;::::0;43027:36:::1;::::0;:50:::1;::::0;42949:63;;43027:50:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;42902:187;;43099:10;:17:::0;;-1:-1:-1;;43099:17:0::1;43112:4;43099:17;::::0;;42852:272::o;2184:155::-;2242:7;2274:1;2270;:5;2262:46;;;;-1:-1:-1;;;2262:46:0;;;;;;;:::i;:::-;2330:1;2326;:5;;;;;;;2184:155;-1:-1:-1;;;2184:155:0:o;2021:::-;2079:9;2109:6;;;:30;;-1:-1:-1;;2124:5:0;;;2138:1;2133;2124:5;2133:1;2119:15;;;;;:20;2109:30;2101:67;;;;-1:-1:-1;;;2101:67:0;;;;;;;:::i;1726:141::-;1819:5;;;1814:16;;;;1806:53;;;;-1:-1:-1;;;1806:53:0;;;;;;;:::i;1875:138::-;1968:5;;;1963:16;;;;1955:50;;;;-1:-1:-1;;;1955:50:0;;;;;;;:::i;60081:4382::-;-1:-1:-1;;;;;70204:18:0;;70173:28;70204:18;;;:8;:18;;;;;70258:19;;70204:18;;-1:-1:-1;;;70258:19:0;;;-1:-1:-1;;;;;70258:19:0;;70292:729;70313:12;:19;70309:23;;70292:729;;;70358:13;70374:12;70387:1;70374:15;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;70374:15:0;;-1:-1:-1;70449:30:0;:22;70374:15;70449;:22::i;:30::-;-1:-1:-1;;;;;70408:17:0;;;;;;:10;:17;;;;;:38;;;:71;;-1:-1:-1;;;;;70408:71:0;;;;-1:-1:-1;;;70408:71:0;-1:-1:-1;;;;;;;;70408:71:0;;;;;;;;;;70559:30;70533:64;;:57;;70559:30;70408:71;70559:30;;;;70533:25;:57::i;:64::-;-1:-1:-1;;;;;70498:17:0;;;;;;;:10;:17;;;;;:32;;:99;;-1:-1:-1;;70498:99:0;;;;;;;;;;;;;70620:22;;;70616:390;;-1:-1:-1;;;;;70821:17:0;;;;;;:10;:17;;;;;:26;70796:87;;70804:8;;70814:5;;70821:26;;:60;;70863:18;;-1:-1:-1;;;;;70863:18:0;70821:60;;70796:87;-1:-1:-1;;;;;70769:17:0;;;;;;;:7;:17;;;;;;;;:24;;;;;;;;;;;;:114;;;;70948:10;:17;;;;;:38;;;70906:32;;;70948:38;70906:32;;;;;:39;;;;;;;;;;-1:-1:-1;;;70948:38:0;;;-1:-1:-1;;;;;70948:38:0;70906:80;;70616:390;-1:-1:-1;70334:3:0;;70292:729;;;-1:-1:-1;;;;;;;;60305:19:0;::::1;60273:29;60305:19:::0;;;:9:::1;:19;::::0;;;;;;;60366:8:::1;:18:::0;;;;;60469:12;;60535:10:::1;::::0;60305:19;;60366:18;;60273:29;;60469:12;60273:29;;60535:10:::1;;::::0;:78:::1;;-1:-1:-1::0;60581:32:0::1;:15;60601:11:::0;60581:19:::1;:32::i;:::-;60549:5;60564:1;60555:6;:10;60549:17;;;;;;;;;::::0;;;::::1;::::0;;;::::1;:28:::0;-1:-1:-1;;;60549:28:0;::::1;;;:64;;60535:78;60531:2561;;;60719:18:::0;;-1:-1:-1;;;;;60719:18:0;;::::1;::::0;-1:-1:-1;;;;60768:19:0;;::::1;;::::0;-1:-1:-1;60882:13:0::1;:6:::0;:11:::1;:13::i;:::-;60852:43:::0;;::::1;::::0;;;::::1;-1:-1:-1::0;;;60852:43:0::1;-1:-1:-1::0;;;;;60852:43:0;;::::1;;::::0;;61255:15;;61251:456:::1;;61291:20;61314:74;37790:9;61314:53;37790:9:::0;61314:32:::1;:15;61334:11:::0;61314:19:::1;:32::i;:::-;:36:::0;::::1;:53::i;:74::-;61291:97;;61407:18;61428:76;37790:9;61428:55;61453:5;61468:1;61459:6;:10;61453:17;;;;;;;;;::::0;;;::::1;::::0;;;::::1;:28:::0;61428:12;;61453:28:::1;-1:-1:-1::0;;;61453:28:0;;::::1;::::0;::::1;::::0;61428:16:::1;:55;:::i;:76::-;61407:97;;61523:13;61539:63;61552:36;61575:10;61586:1;61575:12;61552:18;;:22;;:36;;;;:::i;:::-;38848:5;61539:12;:63::i;:::-;61523:79;;61630:61;38848:5;61630:44;61668:5;61638;61653:1;61644:6;:10;61638:17;;;;;;;;;::::0;;;::::1;::::0;;;::::1;:24:::0;-1:-1:-1;;;;;61638:24:0::1;::::0;61630:37:::1;:44::i;:61::-;61621:70;;61251:456;;;;60531:2561;;;61893:27:::0;;-1:-1:-1;;;61893:27:0;::::1;;;::::0;61935:1046:::1;61970:6;61966:1;:10;61935:1046;;;62089:32;:15;62109:11:::0;62089:19:::1;:32::i;:::-;62067:5;62073:1;62067:8;;;;;;;;;::::0;;;::::1;::::0;;;::::1;:19:::0;-1:-1:-1;;;62067:19:0;::::1;;;:54;62063:65;;;62123:5;;62063:65;62203:27;62214:5;62220:1;62214:8;;;;;;;;;::::0;;;::::1;::::0;;;::::1;:15:::0;-1:-1:-1;;;;;62203:10:0;;::::1;::::0;62214:15:::1;62203:10;:27::i;:::-;62194:36;;62265:35;62283:5;62289:1;62283:8;;;;;;;;;::::0;;;::::1;::::0;;;::::1;:16:::0;-1:-1:-1;;;;;62265:17:0;;::::1;::::0;-1:-1:-1;;;62283:16:0;::::1;;62265:17;:35::i;:::-;62249:51:::0;-1:-1:-1;62422:15:0;;62418:471:::1;;62462:20;62485:74;37790:9;62485:53;37790:9;62485:32;62505:11;62485:15;:19;;:32;;;;:::i;:74::-;62462:97;;62582:18;62603:67;37790:9;62603:46;62628:5;62634:1;62628:8;;;;;;;62603:67;62582:88;;62693:13;62709:63;62722:36;62745:10;62756:1;62745:12;62722:18;;:22;;:36;;;;:::i;62709:63::-;62693:79;;62804:65;62816:52;38848:5;62816:35;62845:5;62824;62830:1;62824:8;;;;;;;62816:52;62804:6:::0;;:10:::1;:65::i;:::-;62795:74;;62418:471;;;;62948:17;::::0;;::::1;::::0;61978:3:::1;61935:1046;;;-1:-1:-1::0;63035:45:0;;::::1;::::0;;::::1;-1:-1:-1::0;;;63035:45:0::1;-1:-1:-1::0;;;;;63035:45:0;;::::1;;::::0;;60531:2561:::1;63119:1;63110:6;-1:-1:-1::0;;;;;63110:10:0::1;;63102:35;;;;-1:-1:-1::0;;;63102:35:0::1;;;;;;;:::i;:::-;63222:18:::0;;:30:::1;::::0;-1:-1:-1;;;;;63222:18:0::1;63245:6:::0;63222:22:::1;:30::i;:::-;63201:51:::0;;-1:-1:-1;;;;;;63201:51:0::1;-1:-1:-1::0;;;;;63201:51:0;;::::1;;::::0;;;63285:38:::1;::::0;-1:-1:-1;;;63285:19:0;;::::1;;63309:13:::0;63285:23:::1;:38::i;:::-;63263:60:::0;;-1:-1:-1;;;;;;;;63263:60:0::1;-1:-1:-1::0;;;;;;;;63263:60:0;;::::1;;;::::0;;63349:12:::1;::::0;:24:::1;::::0;;::::1;:16;:24::i;:::-;63334:12;:39:::0;63400:13:::1;::::0;:32:::1;::::0;-1:-1:-1;;;;;63400:32:0;::::1;:17;:32::i;:::-;63384:13;:48;;;;63460:8;-1:-1:-1::0;;;;;63450:36:0::1;;63470:6;63478:7;63450:36;;;;;;;:::i;:::-;;;;;;;;63537:10:::0;;63533:719:::1;;63735:39;63766:6;-1:-1:-1::0;;;;;63758:15:0::1;63735:22;:39::i;:::-;63855:26;63866:14;:6;:12;:14::i;:::-;-1:-1:-1::0;;;;;63855:10:0;::::1;::::0;::::1;:26::i;:::-;63846:35;;63941:42;63953:14;63969:6;63977:5;63941:11;:42::i;:::-;64032:8;-1:-1:-1::0;;;;;64005:44:0::1;64016:14;-1:-1:-1::0;;;;;64005:44:0::1;;64042:6;64005:44;;;;;;:::i;:::-;;;;;;;;63533:719;;;64069:15:::0;;64066:186:::1;;64165:75;64189:49;38848:5;64189:32;-1:-1:-1::0;;;;;64189:15:0;::::1;64209:11:::0;64189:19:::1;:32::i;:49::-;64165:22;:75::i;:::-;64304:7;64300:156;;;64328:45;64334:11;64347:6;-1:-1:-1::0;;;;;64328:45:0::1;64355:11;64368:4;64328:5;:45::i;:::-;64300:156;;;64406:38;64418:11;64431:6;-1:-1:-1::0;;;;;64406:38:0::1;64439:4;64406:11;:38::i;:::-;71042:1;;;;;;60081:4382:::0;;;;;;;:::o;44448:150::-;44526:7;44552:38;44561:15;44578:11;44552:8;:38::i;30276:106::-;30364:10;30276:106;:::o;43522:583::-;43592:7;43616:13;;43633:1;43616:18;43612:104;;;-1:-1:-1;;;;;;43658:25:0;;;;;;:10;:25;;;;;:46;;;-1:-1:-1;;;43658:46:0;;-1:-1:-1;;;;;43658:46:0;43651:53;;43612:104;-1:-1:-1;;;;;44020:25:0;;;;;;:10;:25;;;;;:34;43742:355;;43816:270;;44020:34;;:65;;44073:12;;44020:65;;;44057:13;;44020:65;-1:-1:-1;;;;;43968:25:0;;;;;;:10;:25;;;;;:36;;43904:40;;;;;43816:199;;44010:4;;43816:189;;-1:-1:-1;;;;;;;;43968:36:0;;;;43816:189;;43904:40;;;;;43816:65;;43968:36;43842:38;;;43816:25;:65::i;:::-;:69;;:129::i;:270::-;-1:-1:-1;;;;;43750:25:0;;;;;;:10;:25;;;;;:46;;;-1:-1:-1;;;43750:46:0;;-1:-1:-1;;;;;43750:46:0;;43742:59;:355::i;3346:161::-;3395:9;-1:-1:-1;;;;;3425:16:0;;;3417:57;;;;-1:-1:-1;;;3417:57:0;;;;;;;:::i;:::-;-1:-1:-1;3497:1:0;3346:161::o;2844:156::-;2892:8;2921:15;;;;2913:55;;;;-1:-1:-1;;;2913:55:0;;;;;;;:::i;44113:327::-;-1:-1:-1;;;;;44402:14:0;;;44242:7;44402:14;;;:7;:14;;;;;;;;:29;;;;;;;;;;;;;44331;;;:22;:29;;;;;:44;;;;;;;;;;44269:163;;44402:29;44269:128;;44392:4;;44269:118;;44296:80;;:30;44417:13;44296:15;:30::i;:80::-;44269:8;;:12;:118::i;:128::-;:132;;:163::i;:::-;44262:170;;44113:327;;;;;;:::o;25716:177::-;25799:86;25819:5;25849:23;;;25874:2;25878:5;25826:58;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;25826:58:0;;;;;;;;;;;;;;-1:-1:-1;;;;;25826:58:0;-1:-1:-1;;;;;;25826:58:0;;;;;;;;;;25799:19;:86::i;26375:622::-;26745:10;;;26744:62;;-1:-1:-1;26761:39:0;;-1:-1:-1;;;26761:39:0;;-1:-1:-1;;;;;26761:15:0;;;;;:39;;26785:4;;26792:7;;26761:39;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;26744:62;26736:152;;;;-1:-1:-1;;;26736:152:0;;;;;;;:::i;:::-;26899:90;26919:5;26949:22;;;26973:7;26982:5;26926:62;;;;;;;;;:::i;66066:1114::-;66133:10;;;;66129:23;;;66145:7;;66129:23;66204:37;;-1:-1:-1;;;66204:37:0;;66188:13;;37447:42;;66204:22;;:37;;66235:4;;66204:37;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;66188:53;;66252:14;66283:12;;;;;;;;;-1:-1:-1;;;;;66283:12:0;-1:-1:-1;;;;;66269:38:0;;:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;66252:57;-1:-1:-1;66320:13:0;66336:17;:5;66252:57;66336:9;:17::i;:::-;66320:33;-1:-1:-1;66377:10:0;66374:22;;66389:7;;;;;66374:22;66440:13;66456:34;66484:5;66456:23;:6;38848:5;66456:10;:23::i;:34::-;66440:50;;66557:12;66572:37;66607:1;66572:30;66589:12;;66572;;:16;;:30;;;;:::i;:37::-;66557:52;;66620:11;66634:25;66651:7;66634:12;;:16;;:25;;;;:::i;:::-;66620:39;;66670:11;66684:46;66693:12;;66722:7;66707:12;;:22;66684:8;:46::i;:::-;66670:60;;66753:3;66745:5;:11;66741:432;;;66795:14;66812:44;66823:32;38848:5;66823:15;:5;66833:4;66823:9;:15::i;:32::-;66812:6;;:10;:44::i;:::-;66885:12;;66871:44;;-1:-1:-1;;;66871:44:0;;66795:61;;-1:-1:-1;;;;;;66885:12:0;;66871:36;;:44;;66795:61;;66871:44;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66741:432;;;;66945:3;66937:5;:11;66933:240;;;66984:16;67003:44;67040:6;67003:32;38848:5;67003:15;:5;67013:4;67003:9;:15::i;:44::-;67088:12;;66984:63;;-1:-1:-1;67062:49:0;;37447:42;;-1:-1:-1;;;;;67088:12:0;66984:63;67062:25;:49::i;:::-;67140:12;;;;;;;;;-1:-1:-1;;;;;67140:12:0;-1:-1:-1;;;;;67126:33:0;;:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66933:240;66066:1114;;;;;;;;:::o;68128:659::-;-1:-1:-1;;;;;68234:25:0;;68211:20;68234:25;;;:10;:25;;;;;68295:18;;;;;;;68276:15;:37;68272:375;;68349:36;:28;:7;37790:9;68349:11;:28::i;:36::-;68330:55;;-1:-1:-1;;;;;68330:55:0;;;;-1:-1:-1;;;68330:55:0;;;;;;;;68272:375;;;68446:18;;68418:17;;68438:48;;68446:18;;;;;68470:15;68438:31;:48::i;:::-;68534:16;;68418:68;;-1:-1:-1;68501:16:0;;68520:31;;68418:68;;-1:-1:-1;;;68534:16:0;;-1:-1:-1;;;;;68534:16:0;68520:13;:31::i;:::-;68501:50;-1:-1:-1;68585:50:0;:42;37790:9;68585:21;:7;68501:50;68585:11;:21::i;:50::-;68566:69;;-1:-1:-1;;;;;68566:69:0;;;;-1:-1:-1;;;68566:69:0;;;;;;;;-1:-1:-1;;68272:375:0;68682:22;:15;:20;:22::i;:::-;68659:20;;;:45;;-1:-1:-1;;68659:45:0;;;;;;;;;;;;68736:43;:36;:15;37790:9;68736:19;:36::i;:43::-;68715:64;;;;;;;;;-1:-1:-1;;68715:64:0;;;;;;-1:-1:-1;;68128:659:0:o;25901:205::-;26002:96;26022:5;26052:27;;;26081:4;26087:2;26091:5;26029:68;;;;;;;;;;:::i;26002:96::-;25901:205;;;;:::o;53789:1103::-;53919:17;53939:78;37790:9;53939:57;37790:9;53939:36;:15;37790:9;53939:19;:36::i;:78::-;54049:6;:13;;53919:98;;-1:-1:-1;53919:98:0;;-1:-1:-1;;54181:14:0;;54174:22;;;;;;;;;;;;;;;;:27;-1:-1:-1;;;54174:27:0;;;;:39;54170:715;;;54265:305;54271:6;54278:13;;54303:9;;54271:6;-1:-1:-1;;54278:15:0;;;54271:23;;;;;;;;;;;;;;;:28;-1:-1:-1;;;54271:28:0;;;;:41;54265:305;;54332:21;54356:58;37790:9;54364:6;54385:1;54371:6;:13;;;;:15;54364:23;;;;;;;54356:58;54445:108;;;;;;;;;-1:-1:-1;54445:108:0;;;;;;;;;;;;;54433:6;:121;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;54433:121:0;-1:-1:-1;;;;;54433:121:0;;;-1:-1:-1;;;;;;54433:121:0;;;;;;;;;;;-1:-1:-1;54265:305:0;;;54656:13;;54643:9;;:26;54640:90;;54701:13;;54689:9;:25;54640:90;54770:23;;54747:19;;:46;54744:130;;54835:23;;54813:19;:45;53789:1103;;:::o;55333:4662::-;55458:1;55448:7;:11;55440:38;;;;-1:-1:-1;;;55440:38:0;;;;;;;:::i;:::-;55512:19;;55497:11;:34;;55489:61;;;;-1:-1:-1;;;55489:61:0;;;;;;;:::i;:::-;55570:10;;;;55569:11;55561:32;;;;-1:-1:-1;;;55561:32:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;55629:18:0;;55606:20;55629:18;;;:8;:18;;;;;55707;:16;:18::i;:::-;55778:19;55800:41;38848:5;55800:24;:7;55812:11;55800;:24::i;:41::-;55778:63;;55852:18;55873:76;55904:19;;55925:1;55904:22;:44;;55929:19;;55904:44;;;55927:1;55904:44;55873:9;;:26;;55887:11;55873:13;:26::i;:76::-;55852:97;-1:-1:-1;55960:18:0;55981:32;:24;:7;55993:11;55981;:24::i;:::-;:30;:32::i;:::-;55960:53;-1:-1:-1;56024:21:0;56048:61;:53;56060:40;38848:5;56060:23;:7;56072:10;56060:11;:23::i;:40::-;56048:7;;:11;:53::i;:61::-;56164:10;;56024:85;;-1:-1:-1;56164:26:0;;-1:-1:-1;;;;;56164:10:0;56179;56164:14;:26::i;:::-;56151:39;;-1:-1:-1;;;;;;56151:39:0;-1:-1:-1;;;;;56151:39:0;;;;;;;56215:30;;-1:-1:-1;;;56215:11:0;;;;56231:13;56215:15;:30::i;:::-;56201:44;;-1:-1:-1;;;;;;;;56201:44:0;-1:-1:-1;;;;;;;;56201:44:0;;;;;;;56306:12;;:28;;;;:16;:28::i;:::-;56291:12;:43;56361:13;;:32;;-1:-1:-1;;;;;56361:32:0;;:17;:32::i;:::-;56345:13;:48;56457:17;56477:57;37790:9;56477:36;:15;37790:9;56477:19;:36::i;:57::-;56457:77;;56609:9;56605:83;;56646:30;:9;37790;56646:13;:30::i;:::-;56634:42;;56605:83;56698:18;56719:27;:9;37894:20;56719:13;:27::i;:::-;-1:-1:-1;;;;;56771:19:0;;56757:11;56771:19;;;:9;:19;;;;;:26;56698:48;;-1:-1:-1;56925:8:0;;;:64;;-1:-1:-1;;;;;;56937:19:0;;;;;;:9;:19;;;;;:28;;56979:10;;56937:19;-1:-1:-1;;56957:7:0;;;56937:28;;;;;;;;;;;;;;;:39;-1:-1:-1;;;56937:39:0;;;;:52;56925:64;56921:2314;;;-1:-1:-1;;;;;57006:19:0;;;;;;:9;:19;;;;;;;;57031:157;;;;;;;-1:-1:-1;;;;;57031:157:0;;;;;;;;;;;;;;;;;;;;;;;;57006:183;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;57006:183:0;-1:-1:-1;;;;;57006:183:0;;;-1:-1:-1;;;57006:183:0;-1:-1:-1;;;;;;;;57006:183:0;;;;-1:-1:-1;;;;;;57006:183:0;;;;;;;;;;;;;;;;56921:2314;;;-1:-1:-1;;;;;57428:19:0;;;;;;:9;:19;;;;;:28;;57470:10;;57428:19;-1:-1:-1;;57448:7:0;;;57428:28;;;;;;;;;;;;;;;:39;-1:-1:-1;;;57428:39:0;;;;:52;57425:96;;;-1:-1:-1;;57500:5:0;57425:96;-1:-1:-1;;;;;57694:19:0;;;;;;:9;:19;;;;;:28;;57737:10;;57694:19;-1:-1:-1;;57714:7:0;;;57694:28;;;;;;;;;;;;;;;:39;-1:-1:-1;;;57694:39:0;;;;:53;57691:1533;;;-1:-1:-1;;;;;57797:19:0;;57767:27;57797:19;;;:9;:19;;;;;:28;;-1:-1:-1;;57817:7:0;;;57797:28;;;;;;;;;;;;;;;57859:12;;57797:28;;-1:-1:-1;57859:28:0;;-1:-1:-1;;;;;57859:12:0;57876:10;57859:16;:28::i;:::-;57844:43;;-1:-1:-1;;;;;;57844:43:0;-1:-1:-1;;;;;57844:43:0;;;;;;;57922:32;;-1:-1:-1;;;57922:13:0;;;;57940;57922:17;:32::i;:::-;57906:48;;-1:-1:-1;;;;;57906:48:0;;;;-1:-1:-1;;;57906:48:0;-1:-1:-1;;;;;;;;57906:48:0;;;;;;57691:1533;;;-1:-1:-1;;;;;;58559:19:0;;;;;;:9;:19;;;;;:26;;;:19;-1:-1:-1;;58697:7:0;;58677:28;;;;;;;;;;;;;;58647:58;;58771:9;:19;58781:8;-1:-1:-1;;;;;58771:19:0;-1:-1:-1;;;;;58771:19:0;;;;;;;;;;;;58796:173;;;;;;;;58841:5;:12;;;;;;;;;;-1:-1:-1;;;;;58841:12:0;-1:-1:-1;;;;;58796:173:0;;;;;58885:5;:13;;;;;;;;;;-1:-1:-1;;;;;58885:13:0;-1:-1:-1;;;;;58796:173:0;;;;;58933:5;:16;;;;;;;;;;;;58796:173;;;;;58771:199;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;58771:199:0;;;;;-1:-1:-1;;;;;58771:199:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;58771:199:0;;;;;-1:-1:-1;;;;;58771:199:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59094:10;59079:5;:12;;;:25;;;;;-1:-1:-1;;;;;59079:25:0;;;;;-1:-1:-1;;;;;59079:25:0;;;;;;59139:13;59123:5;:13;;;:29;;;;;-1:-1:-1;;;;;59123:29:0;;;;;-1:-1:-1;;;;;59123:29:0;;;;;;59197:10;59171:5;:16;;;:37;;;;;;;;;;;;;;;;;;57691:1533;;59356:6;:13;-1:-1:-1;;59356:17:0;59484:48;;;;-1:-1:-1;;59512:8:0;59484:48;59542:15;59560:6;59567;59560:14;;;;;;;;;;;;;;;;;59596:8;;59560:14;;-1:-1:-1;59596:36:0;;-1:-1:-1;;;;;59596:8:0;-1:-1:-1;;;;;59609:22:0;;59596:12;:36::i;:::-;59585:47;;-1:-1:-1;;;;;;59585:47:0;-1:-1:-1;;;;;59585:47:0;;;;;;;59679:15;;59675:100;;59737:12;;59711:52;;37447:42;;-1:-1:-1;;;;;59737:12:0;59751:11;59711:25;:52::i;:::-;59871:35;39137:3;59871:16;:35::i;:::-;59941:9;59931:8;-1:-1:-1;;;;;59924:63:0;;59952:7;59961:10;59973:13;59924:63;;;;;;;;:::i;:::-;;;;;;;;55333:4662;;;;;;;;;;;;;;:::o;2680:156::-;2728:8;2757:15;;;;2749:55;;;;-1:-1:-1;;;2749:55:0;;;;;;;:::i;275:106::-;333:7;364:1;360;:5;:13;;372:1;360:13;;;-1:-1:-1;368:1:0;;353:20;-1:-1:-1;275:106:0:o;5387:141::-;5480:5;;;-1:-1:-1;;;;;5475:16:0;;;;;;;;5467:53;;;;-1:-1:-1;;;5467:53:0;;;;;;;:::i;5536:138::-;5629:5;;;-1:-1:-1;;;;;5624:16:0;;;;;;;;5616:50;;;;-1:-1:-1;;;5616:50:0;;;;;;;:::i;65283:249::-;65369:37;;-1:-1:-1;;;65369:37:0;;65351:15;;37447:42;;65369:22;;:37;;65400:4;;65369:37;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;65351:55;;65431:7;65421;:17;65417:108;;;65469:12;;-1:-1:-1;;;;;65469:12:0;65455:36;65492:20;:7;65504;65492:11;:20::i;:::-;65455:58;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;65283:249;;:::o;3008:161::-;3057:9;-1:-1:-1;;;;;3087:16:0;;;3079:57;;;;-1:-1:-1;;;3079:57:0;;;;;;;:::i;65623:370::-;65779:31;65802:7;65779:22;:31::i;:::-;65841:44;37447:42;65867:8;65877:7;65841:25;:44::i;:::-;65927:12;65924:62;;;65955:19;65972:1;65955:16;:19::i;28021:761::-;28445:23;28471:69;28499:4;28471:69;;;;;;;;;;;;;;;;;28479:5;-1:-1:-1;;;;;28471:27:0;;;:69;;;;;:::i;:::-;28555:17;;28445:95;;-1:-1:-1;28555:21:0;28551:224;;28697:10;28686:30;;;;;;;;;;;;:::i;:::-;28678:85;;;;-1:-1:-1;;;28678:85:0;;;;;;;:::i;6140:141::-;6233:5;;;-1:-1:-1;;;;;6228:16:0;;;;;;;;6220:53;;;;-1:-1:-1;;;6220:53:0;;;;;;;:::i;20717:195::-;20820:12;20852:52;20874:6;20882:4;20888:1;20891:12;20820;22021:18;22032:6;22021:10;:18::i;:::-;22013:60;;;;-1:-1:-1;;;22013:60:0;;;;;;;:::i;:::-;22147:12;22161:23;22188:6;-1:-1:-1;;;;;22188:11:0;22208:5;22216:4;22188:33;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22146:75;;;;22239:52;22257:7;22266:10;22278:12;22239:17;:52::i;:::-;22232:59;21769:530;-1:-1:-1;;;;;;;21769:530:0:o;17799:422::-;18166:20;18205:8;;;17799:422::o;24309:742::-;24424:12;24453:7;24449:595;;;-1:-1:-1;24484:10:0;24477:17;;24449:595;24598:17;;:21;24594:439;;24861:10;24855:17;24922:15;24909:10;24905:2;24901:19;24894:44;24809:148;25004:12;24997:20;;-1:-1:-1;;;24997:20:0;;;;;;;;:::i;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;:::o;5:130::-;72:20;;-1:-1;;;;;42557:54;;44107:35;;44097:2;;44156:1;;44146:12;686:241;;790:2;778:9;769:7;765:23;761:32;758:2;;;-1:-1;;796:12;758:2;858:53;903:7;879:22;858:53;:::i;934:366::-;;;1055:2;1043:9;1034:7;1030:23;1026:32;1023:2;;;-1:-1;;1061:12;1023:2;1123:53;1168:7;1144:22;1123:53;:::i;:::-;1113:63;;1231:53;1276:7;1213:2;1256:9;1252:22;1231:53;:::i;:::-;1221:63;;1017:283;;;;;:::o;1307:485::-;;;;1442:2;1430:9;1421:7;1417:23;1413:32;1410:2;;;-1:-1;;1448:12;1410:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;1500:63;-1:-1;1600:2;1639:22;;72:20;97:33;72:20;97:33;:::i;:::-;1608:63;-1:-1;1708:2;1744:22;;206:20;231:30;206:20;231:30;:::i;:::-;1716:60;;;;1404:388;;;;;:::o;1799:360::-;;;1917:2;1905:9;1896:7;1892:23;1888:32;1885:2;;;-1:-1;;1923:12;1885:2;1985:53;2030:7;2006:22;1985:53;:::i;:::-;1975:63;;2075:2;2115:9;2111:22;206:20;231:30;255:5;231:30;:::i;:::-;2083:60;;;;1879:280;;;;;:::o;2166:366::-;;;2287:2;2275:9;2266:7;2262:23;2258:32;2255:2;;;-1:-1;;2293:12;2255:2;2355:53;2400:7;2376:22;2355:53;:::i;:::-;2345:63;2445:2;2484:22;;;;475:20;;-1:-1;;;2249:283::o;2539:491::-;;;;2677:2;2665:9;2656:7;2652:23;2648:32;2645:2;;;-1:-1;;2683:12;2645:2;2745:53;2790:7;2766:22;2745:53;:::i;:::-;2735:63;2835:2;2874:22;;475:20;;-1:-1;2943:2;2982:22;;;475:20;;2639:391;-1:-1;;;2639:391::o;3037:235::-;;3138:2;3126:9;3117:7;3113:23;3109:32;3106:2;;;-1:-1;;3144:12;3106:2;219:6;206:20;231:30;255:5;231:30;:::i;3279:257::-;;3391:2;3379:9;3370:7;3366:23;3362:32;3359:2;;;-1:-1;;3397:12;3359:2;354:6;348:13;366:30;390:5;366:30;:::i;3543:241::-;;3647:2;3635:9;3626:7;3622:23;3618:32;3615:2;;;-1:-1;;3653:12;3615:2;-1:-1;475:20;;3609:175;-1:-1;3609:175::o;3791:263::-;;3906:2;3894:9;3885:7;3881:23;3877:32;3874:2;;;-1:-1;;3912:12;3874:2;-1:-1;623:13;;3868:186;-1:-1;3868:186::o;4061:366::-;;;4182:2;4170:9;4161:7;4157:23;4153:32;4150:2;;;-1:-1;;4188:12;4150:2;488:6;475:20;4240:63;;4358:53;4403:7;4340:2;4383:9;4379:22;4358:53;:::i;4434:366::-;;;4555:2;4543:9;4534:7;4530:23;4526:32;4523:2;;;-1:-1;;4561:12;4523:2;-1:-1;;475:20;;;4713:2;4752:22;;;475:20;;-1:-1;4517:283::o;4807:491::-;;;;4945:2;4933:9;4924:7;4920:23;4916:32;4913:2;;;-1:-1;;4951:12;4913:2;488:6;475:20;5003:63;;5103:2;5146:9;5142:22;475:20;5111:63;;5211:2;5254:9;5250:22;72:20;97:33;124:5;97:33;:::i;21476:271::-;;8430:5;40669:12;8541:52;8586:6;8581:3;8574:4;8567:5;8563:16;8541:52;:::i;:::-;8605:16;;;;;21610:137;-1:-1;;21610:137::o;21754:222::-;-1:-1;;;;;42557:54;;;;5966:37;;21881:2;21866:18;;21852:124::o;21983:333::-;-1:-1;;;;;42557:54;;;5966:37;;42557:54;;22302:2;22287:18;;5966:37;22138:2;22123:18;;22109:207::o;22323:444::-;-1:-1;;;;;42557:54;;;5966:37;;42557:54;;;;22670:2;22655:18;;5966:37;22753:2;22738:18;;20852:37;;;;22506:2;22491:18;;22477:290::o;22774:333::-;-1:-1;;;;;42557:54;;;;5966:37;;23093:2;23078:18;;20852:37;22929:2;22914:18;;22900:207::o;23114:482::-;23347:2;23361:47;;;40669:12;;23332:18;;;41578:19;;;23114:482;;23347:2;41618:14;;;;;;40306;;;23114:482;6758:344;6783:6;6780:1;6777:13;6758:344;;;6844:13;;19189:23;;-1:-1;;;;;42557:54;5966:37;;19351:16;;19345:23;19422:14;;;20852:37;5571:14;;;;41259;;;;42568:42;6798:9;6758:344;;;-1:-1;23414:172;;23318:278;-1:-1;;;;;;;23318:278::o;23603:210::-;42353:13;;42346:21;8224:34;;23724:2;23709:18;;23695:118::o;23820:648::-;42353:13;;42346:21;8224:34;;43153:12;43142:24;;;24206:2;24191:18;;21314:36;-1:-1;;;;;42685:66;;;24289:2;24274:18;;20622:37;43142:24;;24370:2;24355:18;;21314:36;42685:66;24453:3;24438:19;;20622:37;24049:3;24034:19;;24020:448::o;24732:310::-;;24879:2;24900:17;24893:47;8939:5;40669:12;41590:6;24879:2;24868:9;24864:18;41578:19;9033:52;9078:6;41618:14;24868:9;41618:14;24879:2;9059:5;9055:16;9033:52;:::i;:::-;44027:7;44011:14;-1:-1;;44007:28;9097:39;;;;41618:14;9097:39;;24850:192;-1:-1;;24850:192::o;25049:416::-;25249:2;25263:47;;;9373:2;25234:18;;;41578:19;-1:-1;;;41618:14;;;9389:44;9452:12;;;25220:245::o;25472:416::-;25672:2;25686:47;;;9703:2;25657:18;;;41578:19;9739:30;41618:14;;;9719:51;9789:12;;;25643:245::o;25895:416::-;26095:2;26109:47;;;10040:2;26080:18;;;41578:19;10076:30;41618:14;;;10056:51;10126:12;;;26066:245::o;26318:416::-;26518:2;26532:47;;;10377:2;26503:18;;;41578:19;10413:34;41618:14;;;10393:55;-1:-1;;;10468:12;;;10461:30;10510:12;;;26489:245::o;26741:416::-;26941:2;26955:47;;;10761:2;26926:18;;;41578:19;-1:-1;;;41618:14;;;10777:37;10833:12;;;26912:245::o;27164:416::-;27364:2;27378:47;;;11084:2;27349:18;;;41578:19;-1:-1;;;41618:14;;;11100:37;11156:12;;;27335:245::o;27587:416::-;27787:2;27801:47;;;11407:2;27772:18;;;41578:19;-1:-1;;;41618:14;;;11423:39;11481:12;;;27758:245::o;28010:416::-;28210:2;28224:47;;;11732:2;28195:18;;;41578:19;-1:-1;;;41618:14;;;11748:36;11803:12;;;28181:245::o;28856:416::-;29056:2;29070:47;;;12438:2;29041:18;;;41578:19;-1:-1;;;41618:14;;;12454:35;12508:12;;;29027:245::o;29279:416::-;29479:2;29493:47;;;12759:2;29464:18;;;41578:19;-1:-1;;;41618:14;;;12775:38;12832:12;;;29450:245::o;29702:416::-;29902:2;29916:47;;;13083:2;29887:18;;;41578:19;13119:26;41618:14;;;13099:47;13165:12;;;29873:245::o;30125:416::-;30325:2;30339:47;;;13416:2;30310:18;;;41578:19;13452:30;41618:14;;;13432:51;13502:12;;;30296:245::o;30548:416::-;30748:2;30762:47;;;13753:1;30733:18;;;41578:19;-1:-1;;;41618:14;;;13768:32;13819:12;;;30719:245::o;30971:416::-;31171:2;31185:47;;;14070:1;31156:18;;;41578:19;-1:-1;;;41618:14;;;14085:30;14134:12;;;31142:245::o;31394:416::-;31594:2;31608:47;;;31579:18;;;41578:19;14421:34;41618:14;;;14401:55;14475:12;;;31565:245::o;31817:416::-;32017:2;32031:47;;;14726:2;32002:18;;;41578:19;14762:31;41618:14;;;14742:52;14813:12;;;31988:245::o;32240:416::-;32440:2;32454:47;;;15064:1;32425:18;;;41578:19;-1:-1;;;41618:14;;;15079:32;15130:12;;;32411:245::o;32663:416::-;32863:2;32877:47;;;15381:1;32848:18;;;41578:19;-1:-1;;;41618:14;;;15396:31;15446:12;;;32834:245::o;33086:416::-;33286:2;33300:47;;;15697:2;33271:18;;;41578:19;15733:31;41618:14;;;15713:52;15784:12;;;33257:245::o;33509:416::-;33709:2;33723:47;;;16035:1;33694:18;;;41578:19;-1:-1;;;41618:14;;;16050:32;16101:12;;;33680:245::o;33932:416::-;34132:2;34146:47;;;16352:2;34117:18;;;41578:19;16388:29;41618:14;;;16368:50;16437:12;;;34103:245::o;34355:416::-;34555:2;34569:47;;;16688:2;34540:18;;;41578:19;16724:34;41618:14;;;16704:55;-1:-1;;;16779:12;;;16772:34;16825:12;;;34526:245::o;34778:416::-;34978:2;34992:47;;;17076:2;34963:18;;;41578:19;17112:30;41618:14;;;17092:51;17162:12;;;34949:245::o;35201:416::-;35401:2;35415:47;;;17413:2;35386:18;;;41578:19;17449:33;41618:14;;;17429:54;17502:12;;;35372:245::o;35624:416::-;35824:2;35838:47;;;17753:1;35809:18;;;41578:19;-1:-1;;;41618:14;;;17768:32;17819:12;;;35795:245::o;36047:416::-;36247:2;36261:47;;;18070:2;36232:18;;;41578:19;18106:34;41618:14;;;18086:55;-1:-1;;;18161:12;;;18154:46;18219:12;;;36218:245::o;36470:416::-;36670:2;36684:47;;;18470:2;36655:18;;;41578:19;18506:26;41618:14;;;18486:47;18552:12;;;36641:245::o;36893:416::-;37093:2;37107:47;;;18803:2;37078:18;;;41578:19;18839:29;41618:14;;;18819:50;18888:12;;;37064:245::o;37316:321::-;-1:-1;;;;;42441:42;;;;20489:50;;42353:13;42346:21;37623:2;37608:18;;8224:34;37465:2;37450:18;;37436:201::o;37644:440::-;-1:-1;;;;;42441:42;;;20249:37;;42441:42;;;;37989:2;37974:18;;20249:37;43058:10;43047:22;;;38070:2;38055:18;;21080:36;37825:2;37810:18;;37796:288::o;38091:329::-;-1:-1;;;;;42825:70;;;;20742:37;;43058:10;43047:22;38406:2;38391:18;;21080:36;38244:2;38229:18;;38215:205::o;38427:222::-;20852:37;;;38554:2;38539:18;;38525:124::o;38656:444::-;20852:37;;;-1:-1;;;;;42441:42;;;39003:2;38988:18;;20489:50;42441:42;39086:2;39071:18;;20489:50;38839:2;38824:18;;38810:290::o;39107:828::-;;39430:3;39419:9;39415:19;20882:5;20859:3;20852:37;39595:2;20882:5;39595:2;39584:9;39580:18;20852:37;39678:2;20882:5;39678:2;39667:9;39663:18;20852:37;39715:2;39430:3;39715:2;39704:9;39700:18;39693:48;39755:170;7499:5;40669:12;41590:6;41585:3;41578:19;41618:14;39419:9;41618:14;7511:124;;39595:2;7737:5;40306:14;7749:21;;-1:-1;7776:353;7801:6;7798:1;7795:13;7776:353;;;7862:13;;19753:23;;-1:-1;;;;;42441:42;;;20249:37;;19916:16;;;19910:23;42441:42;19987:14;;;20249:37;20076:16;;20070:23;43058:10;43047:22;20145:14;;;21080:36;41259:14;;;;5877;;;;7823:1;7816:9;7776:353;;;-1:-1;39747:178;;39401:534;-1:-1;;;;;;;;;;;39401:534::o;39942:214::-;43249:4;43238:16;;;;21429:35;;40065:2;40050:18;;40036:120::o;43667:268::-;43732:1;43739:101;43753:6;43750:1;43747:13;43739:101;;;43820:11;;;43814:18;43801:11;;;43794:39;43775:2;43768:10;43739:101;;;43855:6;43852:1;43849:13;43846:2;;;-1:-1;;43732:1;43902:16;;43895:27;43716:219::o;44048:117::-;-1:-1;;;;;42557:54;;44107:35;;44097:2;;44156:1;;44146:12;44172:111;44253:5;42353:13;42346:21;44231:5;44228:32;44218:2;;44274:1;;44264:12
Swarm Source
ipfs://0daca5079d08a2a2879895b2312c0d991308583c3b5872c6c0d9298447003536
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.