Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 13037858 | 1089 days ago | IN | 0 ETH | 0.21883156 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
StakingV1_1
Compiler Version
v0.5.17+commit.d19bba13
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-08-17 */ /** * Copyright 2017-2020, bZeroX, LLC <https://bzx.network/>. All Rights Reserved. * Licensed under the Apache License, Version 2.0. */ pragma solidity 0.5.17; pragma experimental ABIEncoderV2; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. * * _Available since v2.4.0._ */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. * * _Available since v2.4.0._ */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. * * _Available since v2.4.0._ */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } /** * @dev Interface of the ERC20 standard as defined in the EIP. Does not include * the optional functions; to access them see {ERC20Detailed}. */ 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); } /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // According to EIP-1052, 0x0 is the value returned for not-yet created accounts // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned // for accounts without code, i.e. `keccak256('')` bytes32 codehash; bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; // solhint-disable-next-line no-inline-assembly assembly { codehash := extcodehash(account) } return (codehash != accountHash && codehash != 0x0); } /** * @dev Converts an `address` into `address payable`. Note that this is * simply a type cast: the actual underlying value is not changed. * * _Available since v2.4.0._ */ function toPayable(address account) internal pure returns (address payable) { return address(uint160(account)); } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. * * _Available since v2.4.0._ */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-call-value (bool success, ) = recipient.call.value(amount)(""); require(success, "Address: unable to send value, recipient may have reverted"); } } /** * @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 ERC20;` 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)); } function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. // A Solidity high level call has three parts: // 1. The target address is checked to verify it contains contract code // 2. The call itself is made, and success asserted // 3. The return value is decoded, which in turn checks the size of the returned data. // solhint-disable-next-line max-line-length require(address(token).isContract(), "SafeERC20: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = address(token).call(data); require(success, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } library MathUtil { /** * @dev Integer division of two numbers, rounding up and truncating the quotient */ function divCeil(uint256 a, uint256 b) internal pure returns (uint256) { return divCeil(a, b, "SafeMath: division by zero"); } /** * @dev Integer division of two numbers, rounding up and truncating the quotient */ function divCeil(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b != 0, errorMessage); if (a == 0) { return 0; } uint256 c = ((a - 1) / b) + 1; return c; } function min256(uint256 _a, uint256 _b) internal pure returns (uint256) { return _a < _b ? _a : _b; } } interface IPriceFeeds { function queryRate( address sourceToken, address destToken) external view returns (uint256 rate, uint256 precision); function queryPrecision( address sourceToken, address destToken) external view returns (uint256 precision); function queryReturn( address sourceToken, address destToken, uint256 sourceAmount) external view returns (uint256 destAmount); function checkPriceDisagreement( address sourceToken, address destToken, uint256 sourceAmount, uint256 destAmount, uint256 maxSlippage) external view returns (uint256 sourceToDestSwapRate); function amountInEth( address Token, uint256 amount) external view returns (uint256 ethAmount); function getMaxDrawdown( address loanToken, address collateralToken, uint256 loanAmount, uint256 collateralAmount, uint256 maintenanceMargin) external view returns (uint256); function getCurrentMarginAndCollateralSize( address loanToken, address collateralToken, uint256 loanAmount, uint256 collateralAmount) external view returns (uint256 currentMargin, uint256 collateralInEthAmount); function getCurrentMargin( address loanToken, address collateralToken, uint256 loanAmount, uint256 collateralAmount) external view returns (uint256 currentMargin, uint256 collateralToLoanRate); function shouldLiquidate( address loanToken, address collateralToken, uint256 loanAmount, uint256 collateralAmount, uint256 maintenanceMargin) external view returns (bool); function getFastGasPrice( address payToken) external view returns (uint256); } contract IVestingToken is IERC20 { function claim() external; function vestedBalanceOf( address _owner) external view returns (uint256); function claimedBalanceOf( address _owner) external view returns (uint256); } /** * @dev Library for managing loan sets * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * Include with `using EnumerableBytes32Set for EnumerableBytes32Set.Bytes32Set;`. * */ library EnumerableBytes32Set { struct Bytes32Set { // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping (bytes32 => uint256) index; bytes32[] values; } /** * @dev Add an address value to a set. O(1). * Returns false if the value was already in the set. */ function addAddress(Bytes32Set storage set, address addrvalue) internal returns (bool) { bytes32 value; assembly { value := addrvalue } return addBytes32(set, value); } /** * @dev Add a value to a set. O(1). * Returns false if the value was already in the set. */ function addBytes32(Bytes32Set storage set, bytes32 value) internal returns (bool) { if (!contains(set, value)){ set.index[value] = set.values.push(value); return true; } else { return false; } } /** * @dev Removes an address value from a set. O(1). * Returns false if the value was not present in the set. */ function removeAddress(Bytes32Set storage set, address addrvalue) internal returns (bool) { bytes32 value; assembly { value := addrvalue } return removeBytes32(set, value); } /** * @dev Removes a value from a set. O(1). * Returns false if the value was not present in the set. */ function removeBytes32(Bytes32Set storage set, bytes32 value) internal returns (bool) { if (contains(set, value)){ uint256 toDeleteIndex = set.index[value] - 1; uint256 lastIndex = set.values.length - 1; // If the element we're deleting is the last one, we can just remove it without doing a swap if (lastIndex != toDeleteIndex) { bytes32 lastValue = set.values[lastIndex]; // Move the last value to the index where the deleted value is set.values[toDeleteIndex] = lastValue; // Update the index for the moved value set.index[lastValue] = toDeleteIndex + 1; // All indexes are 1-based } // Delete the index entry for the deleted value delete set.index[value]; // Delete the old entry for the moved value set.values.pop(); return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return set.index[value] != 0; } /** * @dev Returns true if the value is in the set. O(1). */ function containsAddress(Bytes32Set storage set, address addrvalue) internal view returns (bool) { bytes32 value; assembly { value := addrvalue } return set.index[value] != 0; } /** * @dev Returns an array with all values in the set. O(N). * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * WARNING: This function may run out of gas on large sets: use {length} and * {get} instead in these cases. */ function enumerate(Bytes32Set storage set, uint256 start, uint256 count) internal view returns (bytes32[] memory output) { uint256 end = start + count; require(end >= start, "addition overflow"); end = set.values.length < end ? set.values.length : end; if (end == 0 || start >= end) { return output; } output = new bytes32[](end-start); for (uint256 i = start; i < end; i++) { output[i-start] = set.values[i]; } return output; } /** * @dev Returns the number of elements on the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return set.values.length; } /** @dev Returns the element stored at position `index` in the set. O(1). * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function get(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return set.values[index]; } /** @dev Returns the element stored at position `index` in the set. O(1). * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function getAddress(Bytes32Set storage set, uint256 index) internal view returns (address) { bytes32 value = set.values[index]; address addrvalue; assembly { addrvalue := value } return addrvalue; } } interface IUniswapV2Router { // 0x38ed1739 function swapExactTokensForTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline) external returns (uint256[] memory amounts); // 0x8803dbee function swapTokensForExactTokens( uint256 amountOut, uint256 amountInMax, address[] calldata path, address to, uint256 deadline) external returns (uint256[] memory amounts); // 0x1f00ca74 function getAmountsIn( uint256 amountOut, address[] calldata path) external view returns (uint256[] memory amounts); // 0xd06ca61f function getAmountsOut( uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts); } interface ICurve3Pool { function add_liquidity( uint256[3] calldata amounts, uint256 min_mint_amount) external; function get_virtual_price() external view returns (uint256); } /// @title A proxy interface for The Protocol /// @author bZeroX /// @notice This is just an interface, not to be deployed itself. /// @dev This interface is to be used for the protocol interactions. interface IBZx { ////// Protocol ////// /// @dev adds or replaces existing proxy module /// @param target target proxy module address function replaceContract(address target) external; /// @dev updates all proxy modules addreses and function signatures. /// sigsArr and targetsArr should be of equal length /// @param sigsArr array of function signatures /// @param targetsArr array of target proxy module addresses function setTargets( string[] calldata sigsArr, address[] calldata targetsArr ) external; /// @dev returns protocol module address given a function signature /// @return module address function getTarget(string calldata sig) external view returns (address); ////// Protocol Settings ////// /// @dev sets price feed contract address. The contract on the addres should implement IPriceFeeds interface /// @param newContract module address for the IPriceFeeds implementation function setPriceFeedContract(address newContract) external; /// @dev sets swaps contract address. The contract on the addres should implement ISwapsImpl interface /// @param newContract module address for the ISwapsImpl implementation function setSwapsImplContract(address newContract) external; /// @dev sets loan pool with assets. Accepts two arrays of equal length /// @param pools array of address of pools /// @param assets array of addresses of assets function setLoanPool(address[] calldata pools, address[] calldata assets) external; /// @dev updates list of supported tokens, it can be use also to disable or enable particualr token /// @param addrs array of address of pools /// @param toggles array of addresses of assets /// @param withApprovals resets tokens to unlimited approval with the swaps integration (kyber, etc.) function setSupportedTokens( address[] calldata addrs, bool[] calldata toggles, bool withApprovals ) external; /// @dev sets lending fee with WEI_PERCENT_PRECISION /// @param newValue lending fee percent function setLendingFeePercent(uint256 newValue) external; /// @dev sets trading fee with WEI_PERCENT_PRECISION /// @param newValue trading fee percent function setTradingFeePercent(uint256 newValue) external; /// @dev sets borrowing fee with WEI_PERCENT_PRECISION /// @param newValue borrowing fee percent function setBorrowingFeePercent(uint256 newValue) external; /// @dev sets affiliate fee with WEI_PERCENT_PRECISION /// @param newValue affiliate fee percent function setAffiliateFeePercent(uint256 newValue) external; /// @dev sets liquidation inncetive percent per loan per token. This is the profit percent /// that liquidator gets in the process of liquidating. /// @param loanTokens array list of loan tokens /// @param collateralTokens array list of collateral tokens /// @param amounts array list of liquidation inncetive amount function setLiquidationIncentivePercent( address[] calldata loanTokens, address[] calldata collateralTokens, uint256[] calldata amounts ) external; /// @dev sets max swap rate slippage percent. /// @param newAmount max swap rate slippage percent. function setMaxDisagreement(uint256 newAmount) external; /// TODO function setSourceBufferPercent(uint256 newAmount) external; /// @dev sets maximum supported swap size in ETH /// @param newAmount max swap size in ETH. function setMaxSwapSize(uint256 newAmount) external; /// @dev sets fee controller address /// @param newController address of the new fees controller function setFeesController(address newController) external; /// @dev withdraws lending fees to receiver. Only can be called by feesController address /// @param tokens array of token addresses. /// @param receiver fees receiver address /// @return amounts array of amounts withdrawn function withdrawFees( address[] calldata tokens, address receiver, FeeClaimType feeType ) external returns (uint256[] memory amounts); /// @dev withdraw protocol token (BZRX) from vesting contract vBZRX /// @param receiver address of BZRX tokens claimed /// @param amount of BZRX token to be claimed. max is claimed if amount is greater than balance. /// @return rewardToken reward token address /// @return withdrawAmount amount function withdrawProtocolToken(address receiver, uint256 amount) external returns (address rewardToken, uint256 withdrawAmount); /// @dev depozit protocol token (BZRX) /// @param amount address of BZRX tokens to deposit function depositProtocolToken(uint256 amount) external; function grantRewards(address[] calldata users, uint256[] calldata amounts) external returns (uint256 totalAmount); // NOTE: this doesn't sanitize inputs -> inaccurate values may be returned if there are duplicates tokens input function queryFees(address[] calldata tokens, FeeClaimType feeType) external view returns (uint256[] memory amountsHeld, uint256[] memory amountsPaid); function priceFeeds() external view returns (address); function swapsImpl() external view returns (address); function logicTargets(bytes4) external view returns (address); function loans(bytes32) external view returns (Loan memory); function loanParams(bytes32) external view returns (LoanParams memory); // we don't use this yet // function lenderOrders(address, bytes32) external returns (Order memory); // function borrowerOrders(address, bytes32) external returns (Order memory); function delegatedManagers(bytes32, address) external view returns (bool); function lenderInterest(address, address) external view returns (LenderInterest memory); function loanInterest(bytes32) external view returns (LoanInterest memory); function feesController() external view returns (address); function lendingFeePercent() external view returns (uint256); function lendingFeeTokensHeld(address) external view returns (uint256); function lendingFeeTokensPaid(address) external view returns (uint256); function borrowingFeePercent() external view returns (uint256); function borrowingFeeTokensHeld(address) external view returns (uint256); function borrowingFeeTokensPaid(address) external view returns (uint256); function protocolTokenHeld() external view returns (uint256); function protocolTokenPaid() external view returns (uint256); function affiliateFeePercent() external view returns (uint256); function liquidationIncentivePercent(address, address) external view returns (uint256); function loanPoolToUnderlying(address) external view returns (address); function underlyingToLoanPool(address) external view returns (address); function supportedTokens(address) external view returns (bool); function maxDisagreement() external view returns (uint256); function sourceBufferPercent() external view returns (uint256); function maxSwapSize() external view returns (uint256); /// @dev get list of loan pools in the system. Ordering is not guaranteed /// @param start start index /// @param count number of pools to return /// @return loanPoolsList array of loan pools function getLoanPoolsList(uint256 start, uint256 count) external view returns (address[] memory loanPoolsList); /// @dev checks whether addreess is a loan pool address /// @return boolean function isLoanPool(address loanPool) external view returns (bool); ////// Loan Settings ////// /// @dev creates new loan param settings /// @param loanParamsList array of LoanParams /// @return loanParamsIdList array of loan ids created function setupLoanParams(LoanParams[] calldata loanParamsList) external returns (bytes32[] memory loanParamsIdList); /// @dev Deactivates LoanParams for future loans. Active loans using it are unaffected. /// @param loanParamsIdList array of loan ids function disableLoanParams(bytes32[] calldata loanParamsIdList) external; /// @dev gets array of LoanParams by given ids /// @param loanParamsIdList array of loan ids /// @return loanParamsList array of LoanParams function getLoanParams(bytes32[] calldata loanParamsIdList) external view returns (LoanParams[] memory loanParamsList); /// @dev Enumerates LoanParams in the system by owner /// @param owner of the loan params /// @param start number of loans to return /// @param count total number of the items /// @return loanParamsList array of LoanParams function getLoanParamsList( address owner, uint256 start, uint256 count ) external view returns (bytes32[] memory loanParamsList); /// @dev returns total loan principal for token address /// @param lender address /// @param loanToken address /// @return total principal of the loan function getTotalPrincipal(address lender, address loanToken) external view returns (uint256); ////// Loan Openings ////// /// @dev This is THE function that borrows or trades on the protocol /// @param loanParamsId id of the LoanParam created beforehand by setupLoanParams function /// @param loanId id of existing loan, if 0, start a new loan /// @param isTorqueLoan boolean whether it is toreque or non torque loan /// @param initialMargin in WEI_PERCENT_PRECISION /// @param sentAddresses array of size 4: /// lender: must match loan if loanId provided /// borrower: must match loan if loanId provided /// receiver: receiver of funds (address(0) assumes borrower address) /// manager: delegated manager of loan unless address(0) /// @param sentValues array of size 5: /// newRate: new loan interest rate /// newPrincipal: new loan size (borrowAmount + any borrowed interest) /// torqueInterest: new amount of interest to escrow for Torque loan (determines initial loan length) /// loanTokenReceived: total loanToken deposit (amount not sent to borrower in the case of Torque loans) /// collateralTokenReceived: total collateralToken deposit /// @param loanDataBytes required when sending ether /// @return principal of the loan and collateral amount function borrowOrTradeFromPool( bytes32 loanParamsId, bytes32 loanId, bool isTorqueLoan, uint256 initialMargin, address[4] calldata sentAddresses, uint256[5] calldata sentValues, bytes calldata loanDataBytes ) external payable returns (LoanOpenData memory); /// @dev sets/disables/enables the delegated manager for the loan /// @param loanId id of the loan /// @param delegated delegated manager address /// @param toggle boolean set enabled or disabled function setDelegatedManager( bytes32 loanId, address delegated, bool toggle ) external; /// @dev estimates margin exposure for simulated position /// @param loanToken address of the loan token /// @param collateralToken address of collateral token /// @param loanTokenSent amout of loan token sent /// @param collateralTokenSent amount of collateral token sent /// @param interestRate yearly interest rate /// @param newPrincipal principal amount of the loan /// @return estimated margin exposure amount function getEstimatedMarginExposure( address loanToken, address collateralToken, uint256 loanTokenSent, uint256 collateralTokenSent, uint256 interestRate, uint256 newPrincipal ) external view returns (uint256); /// @dev calculates required collateral for simulated position /// @param loanToken address of loan token /// @param collateralToken address of collateral token /// @param newPrincipal principal amount of the loan /// @param marginAmount margin amount of the loan /// @param isTorqueLoan boolean torque or non torque loan /// @return collateralAmountRequired amount required function getRequiredCollateral( address loanToken, address collateralToken, uint256 newPrincipal, uint256 marginAmount, bool isTorqueLoan ) external view returns (uint256 collateralAmountRequired); function getRequiredCollateralByParams( bytes32 loanParamsId, uint256 newPrincipal ) external view returns (uint256 collateralAmountRequired); /// @dev calculates borrow amount for simulated position /// @param loanToken address of loan token /// @param collateralToken address of collateral token /// @param collateralTokenAmount amount of collateral token sent /// @param marginAmount margin amount /// @param isTorqueLoan boolean torque or non torque loan /// @return borrowAmount possible borrow amount function getBorrowAmount( address loanToken, address collateralToken, uint256 collateralTokenAmount, uint256 marginAmount, bool isTorqueLoan ) external view returns (uint256 borrowAmount); function getBorrowAmountByParams( bytes32 loanParamsId, uint256 collateralTokenAmount ) external view returns (uint256 borrowAmount); ////// Loan Closings ////// /// @dev liquidates unhealty loans /// @param loanId id of the loan /// @param receiver address receiving liquidated loan collateral /// @param closeAmount amount to close denominated in loanToken /// @return loanCloseAmount amount of the collateral token of the loan /// @return seizedAmount sezied amount in the collateral token /// @return seizedToken loan token address function liquidate( bytes32 loanId, address receiver, uint256 closeAmount ) external payable returns ( uint256 loanCloseAmount, uint256 seizedAmount, address seizedToken ); /// @dev rollover loan /// @param loanId id of the loan /// @param loanDataBytes reserved for future use. function rollover(bytes32 loanId, bytes calldata loanDataBytes) external returns (address rebateToken, uint256 gasRebate); /// @dev close position with loan token deposit /// @param loanId id of the loan /// @param receiver collateral token reciever address /// @param depositAmount amount of loan token to deposit /// @return loanCloseAmount loan close amount /// @return withdrawAmount loan token withdraw amount /// @return withdrawToken loan token address function closeWithDeposit( bytes32 loanId, address receiver, uint256 depositAmount // denominated in loanToken ) external payable returns ( uint256 loanCloseAmount, uint256 withdrawAmount, address withdrawToken ); /// @dev close position with swap /// @param loanId id of the loan /// @param receiver collateral token reciever address /// @param swapAmount amount of loan token to swap /// @param returnTokenIsCollateral boolean whether to return tokens is collateral /// @param loanDataBytes reserved for future use /// @return loanCloseAmount loan close amount /// @return withdrawAmount loan token withdraw amount /// @return withdrawToken loan token address function closeWithSwap( bytes32 loanId, address receiver, uint256 swapAmount, // denominated in collateralToken bool returnTokenIsCollateral, // true: withdraws collateralToken, false: withdraws loanToken bytes calldata loanDataBytes ) external returns ( uint256 loanCloseAmount, uint256 withdrawAmount, address withdrawToken ); ////// Loan Closings With Gas Token ////// /// @dev liquidates unhealty loans by using Gas token /// @param loanId id of the loan /// @param receiver address receiving liquidated loan collateral /// @param gasTokenUser user address of the GAS token /// @param closeAmount amount to close denominated in loanToken /// @return loanCloseAmount loan close amount /// @return seizedAmount loan token withdraw amount /// @return seizedToken loan token address function liquidateWithGasToken( bytes32 loanId, address receiver, address gasTokenUser, uint256 closeAmount // denominated in loanToken ) external payable returns ( uint256 loanCloseAmount, uint256 seizedAmount, address seizedToken ); /// @dev rollover loan /// @param loanId id of the loan /// @param gasTokenUser user address of the GAS token function rolloverWithGasToken( bytes32 loanId, address gasTokenUser, bytes calldata /*loanDataBytes*/ ) external returns (address rebateToken, uint256 gasRebate); /// @dev close position with loan token deposit /// @param loanId id of the loan /// @param receiver collateral token reciever address /// @param gasTokenUser user address of the GAS token /// @param depositAmount amount of loan token to deposit denominated in loanToken /// @return loanCloseAmount loan close amount /// @return withdrawAmount loan token withdraw amount /// @return withdrawToken loan token address function closeWithDepositWithGasToken( bytes32 loanId, address receiver, address gasTokenUser, uint256 depositAmount ) external payable returns ( uint256 loanCloseAmount, uint256 withdrawAmount, address withdrawToken ); /// @dev close position with swap /// @param loanId id of the loan /// @param receiver collateral token reciever address /// @param gasTokenUser user address of the GAS token /// @param swapAmount amount of loan token to swap denominated in collateralToken /// @param returnTokenIsCollateral true: withdraws collateralToken, false: withdraws loanToken /// @return loanCloseAmount loan close amount /// @return withdrawAmount loan token withdraw amount /// @return withdrawToken loan token address function closeWithSwapWithGasToken( bytes32 loanId, address receiver, address gasTokenUser, uint256 swapAmount, bool returnTokenIsCollateral, bytes calldata loanDataBytes ) external returns ( uint256 loanCloseAmount, uint256 withdrawAmount, address withdrawToken ); ////// Loan Maintenance ////// /// @dev deposit collateral to existing loan /// @param loanId existing loan id /// @param depositAmount amount to deposit which must match msg.value if ether is sent function depositCollateral(bytes32 loanId, uint256 depositAmount) external payable; /// @dev withdraw collateral from existing loan /// @param loanId existing lona id /// @param receiver address of withdrawn tokens /// @param withdrawAmount amount to withdraw /// @return actualWithdrawAmount actual amount withdrawn function withdrawCollateral( bytes32 loanId, address receiver, uint256 withdrawAmount ) external returns (uint256 actualWithdrawAmount); /// @dev withdraw accrued interest rate for a loan given token address /// @param loanToken loan token address function withdrawAccruedInterest(address loanToken) external; /// @dev extends loan duration by depositing more collateral /// @param loanId id of the existing loan /// @param depositAmount amount to deposit /// @param useCollateral boolean whether to extend using collateral or deposit amount /// @return secondsExtended by that number of seconds loan duration was extended function extendLoanDuration( bytes32 loanId, uint256 depositAmount, bool useCollateral, bytes calldata // for future use /*loanDataBytes*/ ) external payable returns (uint256 secondsExtended); /// @dev reduces loan duration by withdrawing collateral /// @param loanId id of the existing loan /// @param receiver address to receive tokens /// @param withdrawAmount amount to withdraw /// @return secondsReduced by that number of seconds loan duration was extended function reduceLoanDuration( bytes32 loanId, address receiver, uint256 withdrawAmount ) external returns (uint256 secondsReduced); function setDepositAmount( bytes32 loanId, uint256 depositValueAsLoanToken, uint256 depositValueAsCollateralToken ) external; function claimRewards(address receiver) external returns (uint256 claimAmount); function transferLoan(bytes32 loanId, address newOwner) external; function rewardsBalanceOf(address user) external view returns (uint256 rewardsBalance); /// @dev Gets current lender interest data totals for all loans with a specific oracle and interest token /// @param lender The lender address /// @param loanToken The loan token address /// @return interestPaid The total amount of interest that has been paid to a lender so far /// @return interestPaidDate The date of the last interest pay out, or 0 if no interest has been withdrawn yet /// @return interestOwedPerDay The amount of interest the lender is earning per day /// @return interestUnPaid The total amount of interest the lender is owned and not yet withdrawn /// @return interestFeePercent The fee retained by the protocol before interest is paid to the lender /// @return principalTotal The total amount of outstading principal the lender has loaned function getLenderInterestData(address lender, address loanToken) external view returns ( uint256 interestPaid, uint256 interestPaidDate, uint256 interestOwedPerDay, uint256 interestUnPaid, uint256 interestFeePercent, uint256 principalTotal ); /// @dev Gets current interest data for a loan /// @param loanId A unique id representing the loan /// @return loanToken The loan token that interest is paid in /// @return interestOwedPerDay The amount of interest the borrower is paying per day /// @return interestDepositTotal The total amount of interest the borrower has deposited /// @return interestDepositRemaining The amount of deposited interest that is not yet owed to a lender function getLoanInterestData(bytes32 loanId) external view returns ( address loanToken, uint256 interestOwedPerDay, uint256 interestDepositTotal, uint256 interestDepositRemaining ); /// @dev gets list of loans of particular user address /// @param user address of the loans /// @param start of the index /// @param count number of loans to return /// @param loanType type of the loan: All(0), Margin(1), NonMargin(2) /// @param isLender whether to list lender loans or borrower loans /// @param unsafeOnly booleat if true return only unsafe loans that are open for liquidation /// @return loansData LoanReturnData array of loans function getUserLoans( address user, uint256 start, uint256 count, LoanType loanType, bool isLender, bool unsafeOnly ) external view returns (LoanReturnData[] memory loansData); function getUserLoansCount(address user, bool isLender) external view returns (uint256); /// @dev gets existing loan /// @param loanId id of existing loan /// @return loanData array of loans function getLoan(bytes32 loanId) external view returns (LoanReturnData memory loanData); /// @dev get current active loans in the system /// @param start of the index /// @param count number of loans to return /// @param unsafeOnly boolean if true return unsafe loan only (open for liquidation) function getActiveLoans( uint256 start, uint256 count, bool unsafeOnly ) external view returns (LoanReturnData[] memory loansData); /// @dev get current active loans in the system /// @param start of the index /// @param count number of loans to return /// @param unsafeOnly boolean if true return unsafe loan only (open for liquidation) /// @param isLiquidatable boolean if true return liquidatable loans only function getActiveLoansAdvanced( uint256 start, uint256 count, bool unsafeOnly, bool isLiquidatable ) external view returns (LoanReturnData[] memory loansData); function getActiveLoansCount() external view returns (uint256); ////// Swap External ////// /// @dev swap thru external integration /// @param sourceToken source token address /// @param destToken destintaion token address /// @param receiver address to receive tokens /// @param returnToSender TODO /// @param sourceTokenAmount source token amount /// @param requiredDestTokenAmount destination token amount /// @param swapData TODO /// @return destTokenAmountReceived destination token received /// @return sourceTokenAmountUsed source token amount used function swapExternal( address sourceToken, address destToken, address receiver, address returnToSender, uint256 sourceTokenAmount, uint256 requiredDestTokenAmount, bytes calldata swapData ) external payable returns ( uint256 destTokenAmountReceived, uint256 sourceTokenAmountUsed ); /// @dev swap thru external integration using GAS /// @param sourceToken source token address /// @param destToken destintaion token address /// @param receiver address to receive tokens /// @param returnToSender TODO /// @param gasTokenUser user address of the GAS token /// @param sourceTokenAmount source token amount /// @param requiredDestTokenAmount destination token amount /// @param swapData TODO /// @return destTokenAmountReceived destination token received /// @return sourceTokenAmountUsed source token amount used function swapExternalWithGasToken( address sourceToken, address destToken, address receiver, address returnToSender, address gasTokenUser, uint256 sourceTokenAmount, uint256 requiredDestTokenAmount, bytes calldata swapData ) external payable returns ( uint256 destTokenAmountReceived, uint256 sourceTokenAmountUsed ); /// @dev calculate simulated return of swap /// @param sourceToken source token address /// @param destToken destination token address /// @param sourceTokenAmount source token amount /// @return amoun denominated in destination token function getSwapExpectedReturn( address sourceToken, address destToken, uint256 sourceTokenAmount ) external view returns (uint256); function owner() external view returns (address); function transferOwnership(address newOwner) external; struct LoanParams { bytes32 id; bool active; address owner; address loanToken; address collateralToken; uint256 minInitialMargin; uint256 maintenanceMargin; uint256 maxLoanTerm; } struct LoanOpenData { bytes32 loanId; uint256 principal; uint256 collateral; } enum LoanType { All, Margin, NonMargin } struct LoanReturnData { bytes32 loanId; uint96 endTimestamp; address loanToken; address collateralToken; uint256 principal; uint256 collateral; uint256 interestOwedPerDay; uint256 interestDepositRemaining; uint256 startRate; uint256 startMargin; uint256 maintenanceMargin; uint256 currentMargin; uint256 maxLoanTerm; uint256 maxLiquidatable; uint256 maxSeizable; uint256 depositValueAsLoanToken; uint256 depositValueAsCollateralToken; } enum FeeClaimType { All, Lending, Trading, Borrowing } struct Loan { bytes32 id; // id of the loan bytes32 loanParamsId; // the linked loan params id bytes32 pendingTradesId; // the linked pending trades id uint256 principal; // total borrowed amount outstanding uint256 collateral; // total collateral escrowed for the loan uint256 startTimestamp; // loan start time uint256 endTimestamp; // for active loans, this is the expected loan end time, for in-active loans, is the actual (past) end time uint256 startMargin; // initial margin when the loan opened uint256 startRate; // reference rate when the loan opened for converting collateralToken to loanToken address borrower; // borrower of this loan address lender; // lender of this loan bool active; // if false, the loan has been fully closed } struct LenderInterest { uint256 principalTotal; // total borrowed amount outstanding of asset uint256 owedPerDay; // interest owed per day for all loans of asset uint256 owedTotal; // total interest owed for all loans of asset (assuming they go to full term) uint256 paidTotal; // total interest paid so far for asset uint256 updatedTimestamp; // last update } struct LoanInterest { uint256 owedPerDay; // interest owed per day for loan uint256 depositTotal; // total escrowed interest for loan uint256 updatedTimestamp; // last update } } /* * @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. */ contract Context { // Empty internal constructor, to prevent people from mistakenly deploying // an instance of this contract, which should be used via inheritance. constructor () internal { } // solhint-disable-previous-line no-empty-blocks function _msgSender() internal view returns (address payable) { return msg.sender; } function _msgData() internal view returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } } /** * @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. * * 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. */ 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 returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(isOwner(), "Ownable: caller is not the owner"); _; } /** * @dev Returns true if the caller is the current owner. */ function isOwner() public view returns (bool) { return _msgSender() == _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 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 onlyOwner { _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). */ function _transferOwnership(address newOwner) internal { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } } interface IMasterChefSushi { struct UserInfo { uint256 amount; uint256 rewardDebt; } function deposit(uint256 _pid, uint256 _amount) external; function withdraw(uint256 _pid, uint256 _amount) external; // Info of each user that stakes LP tokens. function userInfo(uint256, address) external view returns (UserInfo memory); function pendingSushi(uint256 _pid, address _user) external view returns (uint256); } interface IStaking { struct AltRewardsUserInfo { uint256 rewardsPerShare; uint256 pendingRewards; } function pendingSushiRewards(address _user) external view returns (uint256); function getCurrentFeeTokens() external view returns (address[] memory); function maxUniswapDisagreement() external view returns (uint256); //Temporary, will remove it after migrationn function stakingRewards(address) external view returns (uint256); function isPaused() external view returns (bool); function fundsWallet() external view returns (address); function callerRewardDivisor() external view returns (uint256); function maxCurveDisagreement() external view returns (uint256); function rewardPercent() external view returns (uint256); function addRewards(uint256 newBZRX, uint256 newStableCoin) external; function stake( address[] calldata tokens, uint256[] calldata values ) external; function stake( address[] calldata tokens, uint256[] calldata values, bool claimSushi ) external; function unstake( address[] calldata tokens, uint256[] calldata values ) external; function unstake( address[] calldata tokens, uint256[] calldata values, bool claimSushi ) external; function earned(address account) external view returns ( uint256 bzrxRewardsEarned, uint256 stableCoinRewardsEarned, uint256 bzrxRewardsVesting, uint256 stableCoinRewardsVesting ); function getVariableWeights() external view returns (uint256 vBZRXWeight, uint256 iBZRXWeight, uint256 LPTokenWeight); function balanceOfByAsset( address token, address account) external view returns (uint256 balance); function balanceOfByAssets( address account) external view returns ( uint256 bzrxBalance, uint256 iBZRXBalance, uint256 vBZRXBalance, uint256 LPTokenBalance, uint256 LPTokenBalanceOld ); function balanceOfStored( address account) external view returns (uint256 vestedBalance, uint256 vestingBalance); function totalSupplyStored() external view returns (uint256 supply); function vestedBalanceForAmount( uint256 tokenBalance, uint256 lastUpdate, uint256 vestingEndTime) external view returns (uint256 vested); function votingBalanceOf( address account, uint256 proposalId) external view returns (uint256 totalVotes); function votingBalanceOfNow( address account) external view returns (uint256 totalVotes); function _setProposalVals( address account, uint256 proposalId) external returns (uint256); function exit() external; function addAltRewards(address token, uint256 amount) external; function pendingAltRewards(address token, address _user) external view returns (uint256); } contract StakingConstants { address public constant BZRX = 0x56d811088235F11C8920698a204A5010a788f4b3; address public constant vBZRX = 0xB72B31907C1C95F3650b64b2469e08EdACeE5e8F; address public constant iBZRX = 0x18240BD9C07fA6156Ce3F3f61921cC82b2619157; address public constant LPToken = 0xa30911e072A0C88D55B5D0A0984B66b0D04569d0; // sushiswap address public constant LPTokenOld = 0xe26A220a341EAca116bDa64cF9D5638A935ae629; // balancer IERC20 public constant curve3Crv = IERC20(0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490); address public constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; address public constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F; address public constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; address public constant USDT = 0xdAC17F958D2ee523a2206206994597C13D831ec7; address public constant SUSHI = 0x6B3595068778DD592e39A122f4f5a5cF09C90fE2; IUniswapV2Router public constant uniswapRouter = IUniswapV2Router(0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F); // sushiswap ICurve3Pool public constant curve3pool = ICurve3Pool(0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7); IBZx public constant bZx = IBZx(0xD8Ee69652E4e4838f2531732a46d1f7F584F0b7f); uint256 public constant cliffDuration = 15768000; // 86400 * 365 * 0.5 uint256 public constant vestingDuration = 126144000; // 86400 * 365 * 4 uint256 internal constant vestingDurationAfterCliff = 110376000; // 86400 * 365 * 3.5 uint256 internal constant vestingStartTimestamp = 1594648800; // start_time uint256 internal constant vestingCliffTimestamp = vestingStartTimestamp + cliffDuration; uint256 internal constant vestingEndTimestamp = vestingStartTimestamp + vestingDuration; uint256 internal constant _startingVBZRXBalance = 889389933e18; // 889,389,933 BZRX address internal constant SUSHI_MASTERCHEF = 0xc2EdaD668740f1aA35E4D8f227fB8E17dcA888Cd; uint256 internal constant BZRX_ETH_SUSHI_MASTERCHEF_PID = 188; uint256 public constant BZRXWeightStored = 1e18; struct DelegatedTokens { address user; uint256 BZRX; uint256 vBZRX; uint256 iBZRX; uint256 LPToken; uint256 totalVotes; } event Stake( address indexed user, address indexed token, address indexed delegate, uint256 amount ); event Unstake( address indexed user, address indexed token, address indexed delegate, uint256 amount ); event AddRewards( address indexed sender, uint256 bzrxAmount, uint256 stableCoinAmount ); event Claim( address indexed user, uint256 bzrxAmount, uint256 stableCoinAmount ); event ChangeDelegate( address indexed user, address indexed oldDelegate, address indexed newDelegate ); event WithdrawFees( address indexed sender ); event ConvertFees( address indexed sender, uint256 bzrxOutput, uint256 stableCoinOutput ); event DistributeFees( address indexed sender, uint256 bzrxRewards, uint256 stableCoinRewards ); event AddAltRewards( address indexed sender, address indexed token, uint256 amount ); event ClaimAltRewards( address indexed user, address indexed token, uint256 amount ); } contract StakingUpgradeable is Ownable { address public implementation; } contract StakingState is StakingUpgradeable { using SafeMath for uint256; using SafeERC20 for IERC20; using EnumerableBytes32Set for EnumerableBytes32Set.Bytes32Set; uint256 public constant initialCirculatingSupply = 1030000000e18 - 889389933e18; address internal constant ZERO_ADDRESS = address(0); bool public isPaused; address public fundsWallet; mapping(address => uint256) internal _totalSupplyPerToken; // token => value mapping(address => mapping(address => uint256)) internal _balancesPerToken; // token => account => value mapping(address => address) public delegate; // user => delegate mapping(address => mapping(address => uint256)) public delegatedPerToken; // token => user => value uint256 public bzrxPerTokenStored; mapping(address => uint256) public bzrxRewardsPerTokenPaid; // user => value mapping(address => uint256) public bzrxRewards; // user => value mapping(address => uint256) public bzrxVesting; // user => value uint256 public stableCoinPerTokenStored; mapping(address => uint256) public stableCoinRewardsPerTokenPaid; // user => value mapping(address => uint256) public stableCoinRewards; // user => value mapping(address => uint256) public stableCoinVesting; // user => value uint256 public vBZRXWeightStored; uint256 public iBZRXWeightStored; uint256 public LPTokenWeightStored; EnumerableBytes32Set.Bytes32Set internal _delegatedSet; uint256 public lastRewardsAddTime; mapping(address => uint256) public vestingLastSync; mapping(address => address[]) public swapPaths; mapping(address => uint256) public stakingRewards; uint256 public rewardPercent = 50e18; uint256 public maxUniswapDisagreement = 3e18; uint256 public maxCurveDisagreement = 3e18; uint256 public callerRewardDivisor = 100; address[] public currentFeeTokens; struct ProposalState { uint256 proposalTime; uint256 iBZRXWeight; uint256 lpBZRXBalance; uint256 lpTotalSupply; } address public governor; mapping(uint256 => ProposalState) internal _proposalState; mapping(address => uint256[]) public altRewardsRounds; // depreciated mapping(address => uint256) public altRewardsPerShare; // token => value // Token => (User => Info) mapping(address => mapping(address => IStaking.AltRewardsUserInfo)) public userAltRewardsPerShare; } contract StakingV1_1 is StakingState, StakingConstants { using MathUtil for uint256; modifier onlyEOA() { require(msg.sender == tx.origin, "unauthorized"); _; } modifier checkPause() { require(!isPaused, "paused"); _; } function getCurrentFeeTokens() external view returns (address[] memory) { return currentFeeTokens; } // View function to see pending sushi rewards on frontend. function pendingSushiRewards(address _user) public view returns (uint256) { uint256 pendingSushi = IMasterChefSushi(SUSHI_MASTERCHEF) .pendingSushi(BZRX_ETH_SUSHI_MASTERCHEF_PID, address(this)); return _pendingAltRewards( SUSHI, _user, balanceOfByAsset(LPToken, _user), pendingSushi.mul(1e12).div(_totalSupplyPerToken[LPToken]) ); } function pendingAltRewards(address token, address _user) external view returns (uint256) { uint256 userSupply = balanceOfByAsset(token, _user); return _pendingAltRewards(token, _user, userSupply, 0); } function _pendingAltRewards(address token, address _user, uint256 userSupply, uint256 extraRewardsPerShare) internal view returns (uint256) { uint256 _altRewardsPerShare = altRewardsPerShare[token].add(extraRewardsPerShare); if (_altRewardsPerShare == 0) return 0; if (userSupply == 0) return 0; IStaking.AltRewardsUserInfo memory altRewardsUserInfo = userAltRewardsPerShare[_user][token]; return altRewardsUserInfo.pendingRewards.add( (_altRewardsPerShare.sub(altRewardsUserInfo.rewardsPerShare)).mul(userSupply).div(1e12) ); } // Withdraw all from sushi masterchef function exitSushi() external onlyOwner { IMasterChefSushi chef = IMasterChefSushi(SUSHI_MASTERCHEF); uint256 balance = chef.userInfo(BZRX_ETH_SUSHI_MASTERCHEF_PID, address(this)).amount; chef.withdraw( BZRX_ETH_SUSHI_MASTERCHEF_PID, balance ); } function _depositToSushiMasterchef(uint256 amount) internal { uint256 sushiBalanceBefore = IERC20(SUSHI).balanceOf(address(this)); IMasterChefSushi(SUSHI_MASTERCHEF).deposit( BZRX_ETH_SUSHI_MASTERCHEF_PID, amount ); uint256 sushiRewards = IERC20(SUSHI).balanceOf(address(this)) - sushiBalanceBefore; if (sushiRewards != 0) { _addAltRewards(SUSHI, sushiRewards); } } function _withdrawFromSushiMasterchef(uint256 amount) internal { uint256 sushiBalanceBefore = IERC20(SUSHI).balanceOf(address(this)); IMasterChefSushi(SUSHI_MASTERCHEF).withdraw( BZRX_ETH_SUSHI_MASTERCHEF_PID, amount ); uint256 sushiRewards = IERC20(SUSHI).balanceOf(address(this)) - sushiBalanceBefore; if (sushiRewards != 0) { _addAltRewards(SUSHI, sushiRewards); } } function stake( address[] memory tokens, uint256[] memory values ) public checkPause updateRewards(msg.sender) { require(tokens.length == values.length, "count mismatch"); address token; uint256 stakeAmount; for (uint256 i = 0; i < tokens.length; i++) { token = tokens[i]; require(token == BZRX || token == vBZRX || token == iBZRX || token == LPToken, "invalid token"); stakeAmount = values[i]; if (stakeAmount == 0) { continue; } uint256 pendingBefore = (token == LPToken) ? pendingSushiRewards(msg.sender) : 0; _balancesPerToken[token][msg.sender] = _balancesPerToken[token][msg.sender].add(stakeAmount); _totalSupplyPerToken[token] = _totalSupplyPerToken[token].add(stakeAmount); IERC20(token).safeTransferFrom(msg.sender, address(this), stakeAmount); // Deposit to sushi masterchef if (token == LPToken) { _depositToSushiMasterchef( IERC20(LPToken).balanceOf(address(this)) ); userAltRewardsPerShare[msg.sender][SUSHI] = IStaking.AltRewardsUserInfo({ rewardsPerShare: altRewardsPerShare[SUSHI], pendingRewards: pendingBefore } ); } emit Stake( msg.sender, token, msg.sender, //currentDelegate, stakeAmount ); } } function unstake( address[] memory tokens, uint256[] memory values ) public checkPause updateRewards(msg.sender) { require(tokens.length == values.length, "count mismatch"); address token; uint256 unstakeAmount; uint256 stakedAmount; for (uint256 i = 0; i < tokens.length; i++) { token = tokens[i]; require(token == BZRX || token == vBZRX || token == iBZRX || token == LPToken || token == LPTokenOld, "invalid token"); unstakeAmount = values[i]; stakedAmount = _balancesPerToken[token][msg.sender]; if (unstakeAmount == 0 || stakedAmount == 0) { continue; } if (unstakeAmount > stakedAmount) { unstakeAmount = stakedAmount; } uint256 pendingBefore = (token == LPToken) ? pendingSushiRewards(msg.sender) : 0; _balancesPerToken[token][msg.sender] = stakedAmount - unstakeAmount; // will not overflow _totalSupplyPerToken[token] = _totalSupplyPerToken[token] - unstakeAmount; // will not overflow if (token == BZRX && IERC20(BZRX).balanceOf(address(this)) < unstakeAmount) { // settle vested BZRX only if needed IVestingToken(vBZRX).claim(); } // Withdraw to sushi masterchef if (token == LPToken) { _withdrawFromSushiMasterchef(unstakeAmount); userAltRewardsPerShare[msg.sender][SUSHI] = IStaking.AltRewardsUserInfo({ rewardsPerShare: altRewardsPerShare[SUSHI], pendingRewards: pendingBefore } ); } IERC20(token).safeTransfer(msg.sender, unstakeAmount); emit Unstake( msg.sender, token, msg.sender, //currentDelegate, unstakeAmount ); } } function claim( bool restake) external checkPause updateRewards(msg.sender) returns (uint256 bzrxRewardsEarned, uint256 stableCoinRewardsEarned, uint256 sushiRewardsEarned) { return _claim(restake); } function claimBzrx() external checkPause updateRewards(msg.sender) returns (uint256 bzrxRewardsEarned) { bzrxRewardsEarned = _claimBzrx(false); emit Claim( msg.sender, bzrxRewardsEarned, 0 ); } function claim3Crv() external checkPause updateRewards(msg.sender) returns (uint256 stableCoinRewardsEarned) { stableCoinRewardsEarned = _claim3Crv(); emit Claim( msg.sender, 0, stableCoinRewardsEarned ); } function claimSushi() external checkPause returns (uint256 sushiRewardsEarned) { sushiRewardsEarned = _claimSushi(); if(sushiRewardsEarned != 0){ emit ClaimAltRewards(msg.sender, SUSHI, sushiRewardsEarned); } } function _claim( bool restake) internal returns (uint256 bzrxRewardsEarned, uint256 stableCoinRewardsEarned, uint256 sushiRewardsEarned) { bzrxRewardsEarned = _claimBzrx(restake); stableCoinRewardsEarned = _claim3Crv(); sushiRewardsEarned = _claimSushi(); emit Claim( msg.sender, bzrxRewardsEarned, stableCoinRewardsEarned ); if(sushiRewardsEarned != 0){ emit ClaimAltRewards(msg.sender, SUSHI, sushiRewardsEarned); } } function _claimBzrx( bool restake) internal returns (uint256 bzrxRewardsEarned) { bzrxRewardsEarned = bzrxRewards[msg.sender]; if (bzrxRewardsEarned != 0) { bzrxRewards[msg.sender] = 0; if (restake) { _restakeBZRX( msg.sender, bzrxRewardsEarned ); } else { if (IERC20(BZRX).balanceOf(address(this)) < bzrxRewardsEarned) { // settle vested BZRX only if needed IVestingToken(vBZRX).claim(); } IERC20(BZRX).transfer(msg.sender, bzrxRewardsEarned); } } } function _claim3Crv() internal returns (uint256 stableCoinRewardsEarned) { stableCoinRewardsEarned = stableCoinRewards[msg.sender]; if (stableCoinRewardsEarned != 0) { stableCoinRewards[msg.sender] = 0; curve3Crv.transfer(msg.sender, stableCoinRewardsEarned); } } function _claimSushi() internal returns (uint256) { address _user = msg.sender; uint256 lptUserSupply = balanceOfByAsset(LPToken, _user); if(lptUserSupply == 0){ return 0; } _depositToSushiMasterchef( IERC20(LPToken).balanceOf(address(this)) ); uint256 pendingSushi = _pendingAltRewards(SUSHI, _user, lptUserSupply, 0); userAltRewardsPerShare[_user][SUSHI] = IStaking.AltRewardsUserInfo({ rewardsPerShare: altRewardsPerShare[SUSHI], pendingRewards: 0 } ); if (pendingSushi != 0) { IERC20(SUSHI).safeTransfer(_user, pendingSushi); } return pendingSushi; } function _restakeBZRX( address account, uint256 amount) internal { _balancesPerToken[BZRX][account] = _balancesPerToken[BZRX][account] .add(amount); _totalSupplyPerToken[BZRX] = _totalSupplyPerToken[BZRX] .add(amount); emit Stake( account, BZRX, account, //currentDelegate, amount ); } function exit() public // unstake() does a checkPause { address[] memory tokens = new address[](4); uint256[] memory values = new uint256[](4); tokens[0] = iBZRX; tokens[1] = LPToken; tokens[2] = vBZRX; tokens[3] = BZRX; values[0] = uint256(-1); values[1] = uint256(-1); values[2] = uint256(-1); values[3] = uint256(-1); unstake(tokens, values); // calls updateRewards _claim(false); } modifier updateRewards(address account) { uint256 _bzrxPerTokenStored = bzrxPerTokenStored; uint256 _stableCoinPerTokenStored = stableCoinPerTokenStored; (uint256 bzrxRewardsEarned, uint256 stableCoinRewardsEarned, uint256 bzrxRewardsVesting, uint256 stableCoinRewardsVesting) = _earned( account, _bzrxPerTokenStored, _stableCoinPerTokenStored ); bzrxRewardsPerTokenPaid[account] = _bzrxPerTokenStored; stableCoinRewardsPerTokenPaid[account] = _stableCoinPerTokenStored; // vesting amounts get updated before sync bzrxVesting[account] = bzrxRewardsVesting; stableCoinVesting[account] = stableCoinRewardsVesting; (bzrxRewards[account], stableCoinRewards[account]) = _syncVesting( account, bzrxRewardsEarned, stableCoinRewardsEarned, bzrxRewardsVesting, stableCoinRewardsVesting ); vestingLastSync[account] = block.timestamp; _; } function earned( address account) external view returns (uint256 bzrxRewardsEarned, uint256 stableCoinRewardsEarned, uint256 bzrxRewardsVesting, uint256 stableCoinRewardsVesting, uint256 sushiRewardsEarned) { (bzrxRewardsEarned, stableCoinRewardsEarned, bzrxRewardsVesting, stableCoinRewardsVesting) = _earned( account, bzrxPerTokenStored, stableCoinPerTokenStored ); (bzrxRewardsEarned, stableCoinRewardsEarned) = _syncVesting( account, bzrxRewardsEarned, stableCoinRewardsEarned, bzrxRewardsVesting, stableCoinRewardsVesting ); // discount vesting amounts for vesting time uint256 multiplier = vestedBalanceForAmount( 1e36, 0, block.timestamp ); bzrxRewardsVesting = bzrxRewardsVesting .sub(bzrxRewardsVesting .mul(multiplier) .div(1e36) ); stableCoinRewardsVesting = stableCoinRewardsVesting .sub(stableCoinRewardsVesting .mul(multiplier) .div(1e36) ); uint256 pendingSushi = IMasterChefSushi(SUSHI_MASTERCHEF) .pendingSushi(BZRX_ETH_SUSHI_MASTERCHEF_PID, address(this)); sushiRewardsEarned = _pendingAltRewards( SUSHI, account, balanceOfByAsset(LPToken, account), pendingSushi.mul(1e12).div(_totalSupplyPerToken[LPToken]) ); } function _earned( address account, uint256 _bzrxPerToken, uint256 _stableCoinPerToken) internal view returns (uint256 bzrxRewardsEarned, uint256 stableCoinRewardsEarned, uint256 bzrxRewardsVesting, uint256 stableCoinRewardsVesting) { uint256 bzrxPerTokenUnpaid = _bzrxPerToken.sub(bzrxRewardsPerTokenPaid[account]); uint256 stableCoinPerTokenUnpaid = _stableCoinPerToken.sub(stableCoinRewardsPerTokenPaid[account]); bzrxRewardsEarned = bzrxRewards[account]; stableCoinRewardsEarned = stableCoinRewards[account]; bzrxRewardsVesting = bzrxVesting[account]; stableCoinRewardsVesting = stableCoinVesting[account]; if (bzrxPerTokenUnpaid != 0 || stableCoinPerTokenUnpaid != 0) { uint256 value; uint256 multiplier; uint256 lastSync; (uint256 vestedBalance, uint256 vestingBalance) = balanceOfStored(account); value = vestedBalance .mul(bzrxPerTokenUnpaid); value /= 1e36; bzrxRewardsEarned = value .add(bzrxRewardsEarned); value = vestedBalance .mul(stableCoinPerTokenUnpaid); value /= 1e36; stableCoinRewardsEarned = value .add(stableCoinRewardsEarned); if (vestingBalance != 0 && bzrxPerTokenUnpaid != 0) { // add new vesting amount for BZRX value = vestingBalance .mul(bzrxPerTokenUnpaid); value /= 1e36; bzrxRewardsVesting = bzrxRewardsVesting .add(value); // true up earned amount to vBZRX vesting schedule lastSync = vestingLastSync[account]; multiplier = vestedBalanceForAmount( 1e36, 0, lastSync ); value = value .mul(multiplier); value /= 1e36; bzrxRewardsEarned = bzrxRewardsEarned .add(value); } if (vestingBalance != 0 && stableCoinPerTokenUnpaid != 0) { // add new vesting amount for 3crv value = vestingBalance .mul(stableCoinPerTokenUnpaid); value /= 1e36; stableCoinRewardsVesting = stableCoinRewardsVesting .add(value); // true up earned amount to vBZRX vesting schedule if (lastSync == 0) { lastSync = vestingLastSync[account]; multiplier = vestedBalanceForAmount( 1e36, 0, lastSync ); } value = value .mul(multiplier); value /= 1e36; stableCoinRewardsEarned = stableCoinRewardsEarned .add(value); } } } function _syncVesting( address account, uint256 bzrxRewardsEarned, uint256 stableCoinRewardsEarned, uint256 bzrxRewardsVesting, uint256 stableCoinRewardsVesting) internal view returns (uint256, uint256) { uint256 lastVestingSync = vestingLastSync[account]; if (lastVestingSync != block.timestamp) { uint256 rewardsVested; uint256 multiplier = vestedBalanceForAmount( 1e36, lastVestingSync, block.timestamp ); if (bzrxRewardsVesting != 0) { rewardsVested = bzrxRewardsVesting .mul(multiplier) .div(1e36); bzrxRewardsEarned += rewardsVested; } if (stableCoinRewardsVesting != 0) { rewardsVested = stableCoinRewardsVesting .mul(multiplier) .div(1e36); stableCoinRewardsEarned += rewardsVested; } uint256 vBZRXBalance = _balancesPerToken[vBZRX][account]; if (vBZRXBalance != 0) { // add vested BZRX to rewards balance rewardsVested = vBZRXBalance .mul(multiplier) .div(1e36); bzrxRewardsEarned += rewardsVested; } } return (bzrxRewardsEarned, stableCoinRewardsEarned); } // note: anyone can contribute rewards to the contract function addDirectRewards( address[] calldata accounts, uint256[] calldata bzrxAmounts, uint256[] calldata stableCoinAmounts) external checkPause returns (uint256 bzrxTotal, uint256 stableCoinTotal) { require(accounts.length == bzrxAmounts.length && accounts.length == stableCoinAmounts.length, "count mismatch"); for (uint256 i = 0; i < accounts.length; i++) { bzrxRewards[accounts[i]] = bzrxRewards[accounts[i]].add(bzrxAmounts[i]); bzrxTotal = bzrxTotal.add(bzrxAmounts[i]); stableCoinRewards[accounts[i]] = stableCoinRewards[accounts[i]].add(stableCoinAmounts[i]); stableCoinTotal = stableCoinTotal.add(stableCoinAmounts[i]); } if (bzrxTotal != 0) { IERC20(BZRX).transferFrom(msg.sender, address(this), bzrxTotal); } if (stableCoinTotal != 0) { curve3Crv.transferFrom(msg.sender, address(this), stableCoinTotal); } } // note: anyone can contribute rewards to the contract function addRewards( uint256 newBZRX, uint256 newStableCoin) external checkPause { if (newBZRX != 0 || newStableCoin != 0) { _addRewards(newBZRX, newStableCoin); if (newBZRX != 0) { IERC20(BZRX).transferFrom(msg.sender, address(this), newBZRX); } if (newStableCoin != 0) { curve3Crv.transferFrom(msg.sender, address(this), newStableCoin); } } } function _addRewards( uint256 newBZRX, uint256 newStableCoin) internal { (vBZRXWeightStored, iBZRXWeightStored, LPTokenWeightStored) = getVariableWeights(); uint256 totalTokens = totalSupplyStored(); require(totalTokens != 0, "nothing staked"); bzrxPerTokenStored = newBZRX .mul(1e36) .div(totalTokens) .add(bzrxPerTokenStored); stableCoinPerTokenStored = newStableCoin .mul(1e36) .div(totalTokens) .add(stableCoinPerTokenStored); lastRewardsAddTime = block.timestamp; emit AddRewards( msg.sender, newBZRX, newStableCoin ); } function addAltRewards(address token, uint256 amount) public { if (amount != 0) { _addAltRewards(token, amount); IERC20(token).transferFrom(msg.sender, address(this), amount); } } function _addAltRewards(address token, uint256 amount) internal { address poolAddress = token == SUSHI ? LPToken : token; uint256 totalSupply = _totalSupplyPerToken[poolAddress]; require(totalSupply != 0, "no deposits"); altRewardsPerShare[token] = altRewardsPerShare[token] .add(amount.mul(1e12).div(totalSupply)); emit AddAltRewards(msg.sender, token, amount); } function getVariableWeights() public view returns (uint256 vBZRXWeight, uint256 iBZRXWeight, uint256 LPTokenWeight) { uint256 totalVested = vestedBalanceForAmount( _startingVBZRXBalance, 0, block.timestamp ); vBZRXWeight = SafeMath.mul(_startingVBZRXBalance - totalVested, 1e18) // overflow not possible .div(_startingVBZRXBalance); iBZRXWeight = _calcIBZRXWeight(); uint256 lpTokenSupply = _totalSupplyPerToken[LPToken]; if (lpTokenSupply != 0) { // staked LP tokens are assumed to represent the total unstaked supply (circulated supply - staked BZRX) uint256 normalizedLPTokenSupply = initialCirculatingSupply + totalVested - _totalSupplyPerToken[BZRX]; LPTokenWeight = normalizedLPTokenSupply .mul(1e18) .div(lpTokenSupply); } } function _calcIBZRXWeight() internal view returns (uint256) { return IERC20(BZRX).balanceOf(iBZRX) .mul(1e50) .div(IERC20(iBZRX).totalSupply()); } function balanceOfByAsset( address token, address account) public view returns (uint256 balance) { balance = _balancesPerToken[token][account]; } function balanceOfByAssets( address account) external view returns ( uint256 bzrxBalance, uint256 iBZRXBalance, uint256 vBZRXBalance, uint256 LPTokenBalance, uint256 LPTokenBalanceOld ) { return ( balanceOfByAsset(BZRX, account), balanceOfByAsset(iBZRX, account), balanceOfByAsset(vBZRX, account), balanceOfByAsset(LPToken, account), balanceOfByAsset(LPTokenOld, account) ); } function balanceOfStored( address account) public view returns (uint256 vestedBalance, uint256 vestingBalance) { uint256 balance = _balancesPerToken[vBZRX][account]; if (balance != 0) { vestingBalance = _balancesPerToken[vBZRX][account] .mul(vBZRXWeightStored) .div(1e18); } vestedBalance = _balancesPerToken[BZRX][account]; balance = _balancesPerToken[iBZRX][account]; if (balance != 0) { vestedBalance = balance .mul(iBZRXWeightStored) .div(1e50) .add(vestedBalance); } balance = _balancesPerToken[LPToken][account]; if (balance != 0) { vestedBalance = balance .mul(LPTokenWeightStored) .div(1e18) .add(vestedBalance); } } function totalSupplyByAsset( address token) external view returns (uint256) { return _totalSupplyPerToken[token]; } function totalSupplyStored() public view returns (uint256 supply) { supply = _totalSupplyPerToken[vBZRX] .mul(vBZRXWeightStored) .div(1e18); supply = _totalSupplyPerToken[BZRX] .add(supply); supply = _totalSupplyPerToken[iBZRX] .mul(iBZRXWeightStored) .div(1e50) .add(supply); supply = _totalSupplyPerToken[LPToken] .mul(LPTokenWeightStored) .div(1e18) .add(supply); } function vestedBalanceForAmount( uint256 tokenBalance, uint256 lastUpdate, uint256 vestingEndTime) public view returns (uint256 vested) { vestingEndTime = vestingEndTime.min256(block.timestamp); if (vestingEndTime > lastUpdate) { if (vestingEndTime <= vestingCliffTimestamp || lastUpdate >= vestingEndTimestamp) { // time cannot be before vesting starts // OR all vested token has already been claimed return 0; } if (lastUpdate < vestingCliffTimestamp) { // vesting starts at the cliff timestamp lastUpdate = vestingCliffTimestamp; } if (vestingEndTime > vestingEndTimestamp) { // vesting ends at the end timestamp vestingEndTime = vestingEndTimestamp; } uint256 timeSinceClaim = vestingEndTime.sub(lastUpdate); vested = tokenBalance.mul(timeSinceClaim) / vestingDurationAfterCliff; // will never divide by 0 } } // Governance Logic // function votingBalanceOf( address account, uint256 proposalId) public view returns (uint256 totalVotes) { return _votingBalanceOf(account, _proposalState[proposalId]); } function votingBalanceOfNow( address account) public view returns (uint256 totalVotes) { return _votingBalanceOf(account, _getProposalState()); } function _setProposalVals( address account, uint256 proposalId) public returns (uint256) { require(msg.sender == governor, "unauthorized"); require(_proposalState[proposalId].proposalTime == 0, "proposal exists"); ProposalState memory newProposal = _getProposalState(); _proposalState[proposalId] = newProposal; return _votingBalanceOf(account, newProposal); } function _getProposalState() internal view returns (ProposalState memory) { return ProposalState({ proposalTime: block.timestamp - 1, iBZRXWeight: _calcIBZRXWeight(), lpBZRXBalance: IERC20(BZRX).balanceOf(LPToken), lpTotalSupply: IERC20(LPToken).totalSupply() }); } function _votingBalanceOf( address account, ProposalState memory proposal) internal view returns (uint256 totalVotes) { uint256 _vestingLastSync = vestingLastSync[account]; if (proposal.proposalTime == 0 || _vestingLastSync > proposal.proposalTime - 1) { return 0; } uint256 _vBZRXBalance = _balancesPerToken[vBZRX][account]; if (_vBZRXBalance != 0) { // staked vBZRX is prorated based on total vested totalVotes = _vBZRXBalance .mul(_startingVBZRXBalance - vestedBalanceForAmount( // overflow not possible _startingVBZRXBalance, 0, proposal.proposalTime ) ).div(_startingVBZRXBalance); // user is attributed a staked balance of vested BZRX, from their last update to the present totalVotes = vestedBalanceForAmount( _vBZRXBalance, _vestingLastSync, proposal.proposalTime ).add(totalVotes); } totalVotes = _balancesPerToken[BZRX][account] .add(bzrxRewards[account]) // unclaimed BZRX rewards count as votes .add(totalVotes); totalVotes = _balancesPerToken[iBZRX][account] .mul(proposal.iBZRXWeight) .div(1e50) .add(totalVotes); // LPToken votes are measured based on amount of underlying BZRX staked totalVotes = proposal.lpBZRXBalance .mul(_balancesPerToken[LPToken][account]) .div(proposal.lpTotalSupply) .add(totalVotes); } // OnlyOwner functions function togglePause( bool _isPaused) external onlyOwner { isPaused = _isPaused; } function setFundsWallet( address _fundsWallet) external onlyOwner { fundsWallet = _fundsWallet; } function setGovernor( address _governor) external onlyOwner { governor = _governor; } function setFeeTokens( address[] calldata tokens) external onlyOwner { currentFeeTokens = tokens; } function setRewardPercent( uint256 _rewardPercent) external onlyOwner { require(_rewardPercent <= 1e20, "value too high"); rewardPercent = _rewardPercent; } function setMaxUniswapDisagreement( uint256 _maxUniswapDisagreement) external onlyOwner { require(_maxUniswapDisagreement != 0, "invalid param"); maxUniswapDisagreement = _maxUniswapDisagreement; } function setMaxCurveDisagreement( uint256 _maxCurveDisagreement) external onlyOwner { require(_maxCurveDisagreement != 0, "invalid param"); maxCurveDisagreement = _maxCurveDisagreement; } function setCallerRewardDivisor( uint256 _callerRewardDivisor) external onlyOwner { require(_callerRewardDivisor != 0, "invalid param"); callerRewardDivisor = _callerRewardDivisor; } function setInitialAltRewardsPerShare() external onlyOwner { uint256 index = altRewardsRounds[SUSHI].length; if(index == 0) { return; } altRewardsPerShare[SUSHI] = altRewardsRounds[SUSHI][index - 1]; } function setBalApproval( address _spender, uint256 _value) external onlyOwner { IERC20(0xba100000625a3754423978a60c9317c58a424e3D).approve(_spender, _value); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"AddAltRewards","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"bzrxAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stableCoinAmount","type":"uint256"}],"name":"AddRewards","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"oldDelegate","type":"address"},{"indexed":true,"internalType":"address","name":"newDelegate","type":"address"}],"name":"ChangeDelegate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"bzrxAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stableCoinAmount","type":"uint256"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ClaimAltRewards","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"bzrxOutput","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stableCoinOutput","type":"uint256"}],"name":"ConvertFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"bzrxRewards","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stableCoinRewards","type":"uint256"}],"name":"DistributeFees","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":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"delegate","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Stake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"delegate","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Unstake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"WithdrawFees","type":"event"},{"constant":true,"inputs":[],"name":"BZRX","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"BZRXWeightStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"DAI","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"LPToken","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"LPTokenOld","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"LPTokenWeightStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SUSHI","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"USDC","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"USDT","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"_setProposalVals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"addAltRewards","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"bzrxAmounts","type":"uint256[]"},{"internalType":"uint256[]","name":"stableCoinAmounts","type":"uint256[]"}],"name":"addDirectRewards","outputs":[{"internalType":"uint256","name":"bzrxTotal","type":"uint256"},{"internalType":"uint256","name":"stableCoinTotal","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"newBZRX","type":"uint256"},{"internalType":"uint256","name":"newStableCoin","type":"uint256"}],"name":"addRewards","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"altRewardsPerShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"altRewardsRounds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"bZx","outputs":[{"internalType":"contract IBZx","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"balanceOfByAsset","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOfByAssets","outputs":[{"internalType":"uint256","name":"bzrxBalance","type":"uint256"},{"internalType":"uint256","name":"iBZRXBalance","type":"uint256"},{"internalType":"uint256","name":"vBZRXBalance","type":"uint256"},{"internalType":"uint256","name":"LPTokenBalance","type":"uint256"},{"internalType":"uint256","name":"LPTokenBalanceOld","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOfStored","outputs":[{"internalType":"uint256","name":"vestedBalance","type":"uint256"},{"internalType":"uint256","name":"vestingBalance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"bzrxPerTokenStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"bzrxRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"bzrxRewardsPerTokenPaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"bzrxVesting","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"callerRewardDivisor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bool","name":"restake","type":"bool"}],"name":"claim","outputs":[{"internalType":"uint256","name":"bzrxRewardsEarned","type":"uint256"},{"internalType":"uint256","name":"stableCoinRewardsEarned","type":"uint256"},{"internalType":"uint256","name":"sushiRewardsEarned","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"claim3Crv","outputs":[{"internalType":"uint256","name":"stableCoinRewardsEarned","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"claimBzrx","outputs":[{"internalType":"uint256","name":"bzrxRewardsEarned","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"claimSushi","outputs":[{"internalType":"uint256","name":"sushiRewardsEarned","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"cliffDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"currentFeeTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"curve3Crv","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"curve3pool","outputs":[{"internalType":"contract ICurve3Pool","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"delegate","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"delegatedPerToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"earned","outputs":[{"internalType":"uint256","name":"bzrxRewardsEarned","type":"uint256"},{"internalType":"uint256","name":"stableCoinRewardsEarned","type":"uint256"},{"internalType":"uint256","name":"bzrxRewardsVesting","type":"uint256"},{"internalType":"uint256","name":"stableCoinRewardsVesting","type":"uint256"},{"internalType":"uint256","name":"sushiRewardsEarned","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"exit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"exitSushi","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"fundsWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCurrentFeeTokens","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getVariableWeights","outputs":[{"internalType":"uint256","name":"vBZRXWeight","type":"uint256"},{"internalType":"uint256","name":"iBZRXWeight","type":"uint256"},{"internalType":"uint256","name":"LPTokenWeight","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"governor","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"iBZRX","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"iBZRXWeightStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"initialCirculatingSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastRewardsAddTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"maxCurveDisagreement","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"maxUniswapDisagreement","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"_user","type":"address"}],"name":"pendingAltRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"pendingSushiRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"rewardPercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"setBalApproval","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_callerRewardDivisor","type":"uint256"}],"name":"setCallerRewardDivisor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"}],"name":"setFeeTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_fundsWallet","type":"address"}],"name":"setFundsWallet","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_governor","type":"address"}],"name":"setGovernor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"setInitialAltRewardsPerShare","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_maxCurveDisagreement","type":"uint256"}],"name":"setMaxCurveDisagreement","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_maxUniswapDisagreement","type":"uint256"}],"name":"setMaxUniswapDisagreement","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_rewardPercent","type":"uint256"}],"name":"setRewardPercent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"stableCoinPerTokenStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"stableCoinRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"stableCoinRewardsPerTokenPaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"stableCoinVesting","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"stake","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"stakingRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"swapPaths","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bool","name":"_isPaused","type":"bool"}],"name":"togglePause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"totalSupplyByAsset","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupplyStored","outputs":[{"internalType":"uint256","name":"supply","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"uniswapRouter","outputs":[{"internalType":"contract IUniswapV2Router","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"unstake","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"userAltRewardsPerShare","outputs":[{"internalType":"uint256","name":"rewardsPerShare","type":"uint256"},{"internalType":"uint256","name":"pendingRewards","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"vBZRX","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"vBZRXWeightStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"tokenBalance","type":"uint256"},{"internalType":"uint256","name":"lastUpdate","type":"uint256"},{"internalType":"uint256","name":"vestingEndTime","type":"uint256"}],"name":"vestedBalanceForAmount","outputs":[{"internalType":"uint256","name":"vested","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"vestingDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"vestingLastSync","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"votingBalanceOf","outputs":[{"internalType":"uint256","name":"totalVotes","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"votingBalanceOfNow","outputs":[{"internalType":"uint256","name":"totalVotes","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]
Contract Creation Code
60806040526802b5e3af16b18800006018556729a2241af62c00006019819055601a556064601b5560006200003c6001600160e01b036200008c16565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35062000090565b3390565b61530880620000a06000396000f3fe608060405234801561001057600080fd5b50600436106104c15760003560e01c8063735de9f711610278578063b6d6d88d1161015c578063d85349f7116100ce578063e9fad8ee11610092578063e9fad8ee14610978578063eb0e8d1a14610980578063ef1c243a14610988578063f2fde38b14610990578063f30127a5146109a3578063fc41aa09146109ab576104c1565b8063d85349f714610945578063dae607db1461094d578063db8bb3a114610955578063e0bab4c414610968578063e53b958d14610970576104c1565b8063c54e44eb11610120578063c54e44eb146108e7578063cf86add5146108ef578063cff361e514610902578063d030205114610915578063d3d204311461091d578063d4d83c9614610932576104c1565b8063b6d6d88d14610888578063bcca1e041461089b578063c1159297146108ae578063c1c5dd27146108c1578063c42cf535146108d4576104c1565b80638caaf9e6116101f5578063ab560e10116101b9578063ab560e1014610837578063abbd3ab11461083f578063ad5c464814610852578063b02eba051461085a578063b187bd261461086d578063b293fdc514610875576104c1565b80638caaf9e6146107e15780638da5cb5b146107f45780638f32d59b146107fc5780639674a93114610811578063a5795eba14610824576104c1565b8063863f2e181161023c578063863f2e18146107a357806386be87a6146107ab57806387359ebe146107be57806389a30271146107d157806389ffc781146107d9576104c1565b8063735de9f7146107655780637f3fd8ba1461076d578063802971a61461078057806382a8af151461078857806383e02cd81461079b576104c1565b80633bb20ece116103aa57806355de54681161031c5780635c60da1b116102e05780635c60da1b1461071f5780636305dc2d14610727578063633e94701461073a57806364e39b871461074257806366067a9514610755578063715018a61461075d576104c1565b806355de5468146106d657806357d159c6146106de57806359d99805146106f157806359dcf522146106f95780635c19a95c1461070c576104c1565b8063481153851161036e578063481153851461069b578063499d7f96146106a35780634fb65036146106b657806352fb1c9d146106be57806353a8f1ec146106c6578063547d0738146106ce576104c1565b80633bb20ece146106525780633d0b00241461065a5780633e1755c71461066257806341adca42146106755780634330c26314610688576104c1565b806317a1d012116104435780632194f3a2116104075780632194f3a2146105e75780632a5522af146105ef5780632d06e5bf146106025780632d81a78e1461060a5780632ee1a86e1461062c578063307e85a41461063f576104c1565b806317a1d0121461059a57806319e772c2146105af5780631c9c4408146105b75780631ca97a2d146105bf5780631d3e3955146105d2576104c1565b80630a4d29241161048a5780630a4d2924146105435780630c340a24146105565780630da47e0a1461055e578063135adff6146105715780631514617e14610592576104c1565b80628cc262146104c65780630114a05e146104f3578063011cee361461051357806302baf1b01461052857806302dd19d91461053b575b600080fd5b6104d96104d4366004614774565b6109be565b6040516104ea9594939291906150a9565b60405180910390f35b610506610501366004614774565b610ba1565b6040516104ea919061503c565b61051b610bb3565b6040516104ea9190614e83565b610506610536366004614774565b610bc5565b610506610be4565b6105066105513660046147cc565b610bea565b61051b610c18565b61050661056c366004614774565b610c27565b61058461057f366004614792565b610c39565b6040516104ea929190615080565b610506610c5d565b6105a2610c65565b6040516104ea9190614f0f565b610506610c7d565b610506610c83565b6105066105cd366004614774565b610c89565b6105e56105e0366004614998565b610c9b565b005b61051b610cea565b6105066105fd3660046147cc565b610cf9565b610506610dab565b61061d61061836600461493e565b610dba565b6040516104ea9392919061508e565b6104d961063a366004614774565b610ea8565b6105e561064d366004614998565b610f4c565b610506610f92565b61051b610f98565b6105e56106703660046147cc565b610fb0565b610506610683366004614774565b611048565b610506610696366004614774565b61105a565b61050661106c565b6105066106b1366004614774565b611193565b6105066111a5565b610506611230565b610506611236565b61051b61123c565b6105e5611254565b6105e56106ec36600461493e565b61133a565b61050661137c565b610584610707366004614774565b611382565b61051b61071a366004614774565b6114ff565b61051b61151a565b610506610735366004614774565b611529565b6105a261153a565b6105e5610750366004614774565b611552565b610506611598565b6105e561159e565b6105a261160c565b61050661077b3660046149f3565b611624565b61051b6116c8565b61051b610796366004614998565b6116e0565b61061d611707565b6105e5611800565b6105066107b9366004614792565b61191b565b6105066107cc366004614792565b611937565b61051b611962565b6105a261197a565b6105e56107ef366004614998565b611992565b61051b6119d8565b6108046119e7565b6040516104ea9190614f01565b61050661081f366004614774565b611a0b565b61058461083236600461483e565b611a1d565b61051b611d0c565b61050661084d366004614774565b611d1e565b61051b611d31565b610506610868366004614774565b611d49565b610804611d5b565b6105e56108833660046147fc565b611d6b565b610506610896366004614792565b611d9b565b6105e56108a93660046148df565b611db8565b6105066108bc3660046147cc565b612276565b6105e56108cf366004614998565b6122bf565b6105e56108e2366004614774565b612311565b61051b612357565b6105e56108fd3660046148df565b61236f565b610506610910366004614774565b61278f565b61050661284b565b610925612851565b6040516104ea9190614ef0565b6105e56109403660046147cc565b6128b3565b610506612910565b610506612917565b61051b6109633660046147cc565b612923565b61051b612958565b610506612970565b6105e5612a82565b610506612c50565b610506612c56565b6105e561099e366004614774565b612dcf565b61051b612dff565b6105e56109b93660046149d4565b612e11565b60008060008060006109d586600754600b54612f27565b929750909550935091506109ec86868686866131b9565b90955093506000610a0c6a0c097ce7bc90715b34b9f160241b8242611624565b9050610a4c610a3f6a0c097ce7bc90715b34b9f160241b610a33878563ffffffff6132be16565b9063ffffffff6132f816565b859063ffffffff61333a16565b9350610a80610a736a0c097ce7bc90715b34b9f160241b610a33868563ffffffff6132be16565b849063ffffffff61333a16565b60405163065509bb60e21b815290935060009073c2edad668740f1aa35e4d8f227fb8e17dca888cd9063195426ec90610ac09060bc90309060040161504a565b60206040518083038186803b158015610ad857600080fd5b505afa158015610aec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610b1091908101906149b6565b9050610b946000805160206152a683398151915289610b3d6000805160206152468339815191528c611937565b60008051602061524683398151915260005260036020527f5874759844300eef58e66fc939769d35d274b05b8c5e2a1c60e48b24299f35b654610b8f90610a338764e8d4a5100063ffffffff6132be16565b61337c565b9250505091939590929450565b60086020526000908152604090205481565b60008051602061524683398151915281565b6001600160a01b0381166000908152600360205260409020545b919050565b601b5481565b601f6020528160005260406000208181548110610c0357fe5b90600052602060002001600091509150505481565b601d546001600160a01b031681565b600d6020526000908152604090205481565b60216020908152600092835260408084209091529082529020805460019091015482565b630784ce0081565b73bebc44782c7db0a1a60cb6fe97d0b483032ff1c781565b600f5481565b60105481565b60096020526000908152604090205481565b610ca36119e7565b610cc85760405162461bcd60e51b8152600401610cbf90614fdc565b60405180910390fd5b80610ce55760405162461bcd60e51b8152600401610cbf90614fec565b601a55565b6002546001600160a01b031681565b601d546000906001600160a01b03163314610d265760405162461bcd60e51b8152600401610cbf90614fcc565b6000828152601e602052604090205415610d525760405162461bcd60e51b8152600401610cbf90614f8c565b610d5a6144f9565b610d62613461565b6000848152601e60209081526040918290208351815590830151600182015590820151600282015560608201516003909101559050610da184826135a7565b9150505b92915050565b6a744f570177f475546c000081565b6000806000600160149054906101000a900460ff1615610dec5760405162461bcd60e51b8152600401610cbf9061500c565b600754600b543391906000808080610e05878787612f27565b6001600160a01b038b1660009081526008602090815260408083208d9055600c82528083208c9055600a8252808320859055600e909152902081905592965090945092509050610e5887858585856131b9565b6001600160a01b0389166000908152600960209081526040808320600d83528184209490945593909255601590915220429055610e948b61378a565b995099509950505050505050509193909250565b6000806000806000610ec86000805160206151e683398151915287611937565b610ee67318240bd9c07fa6156ce3f3f61921cc82b261915788611937565b610f0473b72b31907c1c95f3650b64b2469e08edacee5e8f89611937565b610f1c6000805160206152468339815191528a611937565b610f3a73e26a220a341eaca116bda64cf9d5638a935ae6298b611937565b939a9299509097509550909350915050565b610f546119e7565b610f705760405162461bcd60e51b8152600401610cbf90614fdc565b80610f8d5760405162461bcd60e51b8152600401610cbf90614fec565b601b55565b600b5481565b73e26a220a341eaca116bda64cf9d5638a935ae62981565b801561104457610fc08282613849565b6040516323b872dd60e01b81526001600160a01b038316906323b872dd90610ff090339030908690600401614e91565b602060405180830381600087803b15801561100a57600080fd5b505af115801561101e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611042919081019061495c565b505b5050565b600e6020526000908152604090205481565b600a6020526000908152604090205481565b600154600090600160a01b900460ff16156110995760405162461bcd60e51b8152600401610cbf9061500c565b600754600b5433919060008080806110b2878787612f27565b6001600160a01b038b1660009081526008602090815260408083208d9055600c82528083208c9055600a8252808320859055600e90915290208190559296509094509250905061110587858585856131b9565b6001600160a01b0389166000908152600960209081526040808320600d83528184209490945593909255601590915290812042905561114390613954565b9750336001600160a01b03167f34fcbac0073d7c3d388e51312faf357774904998eeb8fca628b9e6f65ee1cbf7896000604051611181929190615065565b60405180910390a25050505050505090565b60176020526000908152604090205481565b600154600090600160a01b900460ff16156111d25760405162461bcd60e51b8152600401610cbf9061500c565b6111da613b0b565b9050801561122d576040516000805160206152a68339815191529033907f24bce930431f78244a70aacbe370a3d06e5fd605a0bb737db20457a7f593e5d09061122490859061503c565b60405180910390a35b90565b60115481565b601a5481565b73b72b31907c1c95f3650b64b2469e08edacee5e8f81565b61125c6119e7565b6112785760405162461bcd60e51b8152600401610cbf90614fdc565b6000805160206152a6833981519152600052601f6020527ff671d343b5ca683fae72ab8c7c043b684239026f02f343b9b49b7056b624a83854806112bc5750611338565b6000805160206152a6833981519152600052601f6020527ff671d343b5ca683fae72ab8c7c043b684239026f02f343b9b49b7056b624a8388054600019830190811061130457fe5b60009182526020808320909101546000805160206152a6833981519152909252805260008051602061522683398151915255505b565b6113426119e7565b61135e5760405162461bcd60e51b8152600401610cbf90614fdc565b60018054911515600160a01b0260ff60a01b19909216919091179055565b60195481565b6001600160a01b03811660009081526000805160206152668339815191526020526040812054819080156113f957600f546001600160a01b038516600090815260008051602061526683398151915260205260409020546113f691670de0b6b3a764000091610a339163ffffffff6132be16565b91505b506001600160a01b038316600090815260008051602061520683398151915260209081526040808320547fe09f1b989ce5e55474fdfb6ab6036e5e02e6f44d8729816a39308c55c71b13c79092529091205490925080156114925761148f836114836e111b0ec57e6499a1f4b1014d3f6d5960321b610a33601054866132be90919063ffffffff16565b9063ffffffff613c1416565b92505b506001600160a01b03831660009081527f064d7c8613d225af78bbf2a77ee533cb03ae723d97d3a14f96452520f45833f2602052604090205480156114f9576114f683611483670de0b6b3a7640000610a33601154866132be90919063ffffffff16565b92505b50915091565b6005602052600090815260409020546001600160a01b031681565b6001546001600160a01b031681565b602080526000908152604090205481565b73d8ee69652e4e4838f2531732a46d1f7f584f0b7f81565b61155a6119e7565b6115765760405162461bcd60e51b8152600401610cbf90614fdc565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b60145481565b6115a66119e7565b6115c25760405162461bcd60e51b8152600401610cbf90614fdc565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b73d9e1ce17f2641f24ae83637ab66a2cca9c378b9f81565b6000611636824263ffffffff613c3916565b9150828211156116c157635ffd02a082111580611657575063669136e08310155b15611664575060006116c1565b635ffd02a083101561167857635ffd02a092505b63669136e082111561168c5763669136e091505b600061169e838563ffffffff61333a16565b905063069434406116b5868363ffffffff6132be16565b816116bc57fe5b049150505b9392505050565b7318240bd9c07fa6156ce3f3f61921cc82b261915781565b601c81815481106116ed57fe5b6000918252602090912001546001600160a01b0316905081565b6000806000806117256b02dfafa4e0948fa071940000600042611624565b90506117576b02dfafa4e0948fa071940000610a33836b02dfafa4e0948fa07194000003670de0b6b3a76400006132be565b9350611761613c4f565b60008051602061524683398151915260005260036020527f5874759844300eef58e66fc939769d35d274b05b8c5e2a1c60e48b24299f35b65490935080156117f9576000805160206151e683398151915260005260036020526000805160206152868339815191525482036a744f570177f475546c0000016117f582610a3383670de0b6b3a764000063ffffffff6132be16565b9350505b5050909192565b6118086119e7565b6118245760405162461bcd60e51b8152600401610cbf90614fdc565b6040516393f1a40b60e01b815273c2edad668740f1aa35e4d8f227fb8e17dca888cd9060009082906393f1a40b906118639060bc90309060040161504a565b604080518083038186803b15801561187a57600080fd5b505afa15801561188e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506118b2919081019061497a565b51604051630441a3e760e41b81529091506001600160a01b0383169063441a3e70906118e59060bc908590600401615080565b600060405180830381600087803b1580156118ff57600080fd5b505af1158015611913573d6000803e3d6000fd5b505050505050565b6000806119288484611937565b9050610da1848483600061337c565b6001600160a01b03918216600090815260046020908152604080832093909416825291909152205490565b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b736c3f90f043a72fa612cbac8115ee7e52bde6e49081565b61199a6119e7565b6119b65760405162461bcd60e51b8152600401610cbf90614fdc565b806119d35760405162461bcd60e51b8152600401610cbf90614fec565b601955565b6000546001600160a01b031690565b600080546001600160a01b03166119fc613d86565b6001600160a01b031614905090565b60156020526000908152604090205481565b6001546000908190600160a01b900460ff1615611a4c5760405162461bcd60e51b8152600401610cbf9061500c565b8685148015611a5a57508683145b611a765760405162461bcd60e51b8152600401610cbf90614f7c565b60005b87811015611bdc57611ae2878783818110611a9057fe5b90506020020135600960008c8c86818110611aa757fe5b9050602002016020611abc9190810190614774565b6001600160a01b031681526020810191909152604001600020549063ffffffff613c1416565b600960008b8b85818110611af257fe5b9050602002016020611b079190810190614774565b6001600160a01b03168152602081019190915260400160002055611b46878783818110611b3057fe5b9050602002013584613c1490919063ffffffff16565b9250611b6e858583818110611b5757fe5b90506020020135600d60008c8c86818110611aa757fe5b600d60008b8b85818110611b7e57fe5b9050602002016020611b939190810190614774565b6001600160a01b03168152602081019190915260400160002055611bd2858583818110611bbc57fe5b9050602002013583613c1490919063ffffffff16565b9150600101611a79565b508115611c6c576040516323b872dd60e01b81526000805160206151e6833981519152906323b872dd90611c1890339030908790600401614e91565b602060405180830381600087803b158015611c3257600080fd5b505af1158015611c46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611c6a919081019061495c565b505b8015611d01576040516323b872dd60e01b8152736c3f90f043a72fa612cbac8115ee7e52bde6e490906323b872dd90611cad90339030908690600401614e91565b602060405180830381600087803b158015611cc757600080fd5b505af1158015611cdb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611cff919081019061495c565b505b965096945050505050565b6000805160206152a683398151915281565b6000610da582611d2c613461565b6135a7565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b600c6020526000908152604090205481565b600154600160a01b900460ff1681565b611d736119e7565b611d8f5760405162461bcd60e51b8152600401610cbf90614fdc565b611042601c8383614521565b600660209081526000928352604080842090915290825290205481565b600154600160a01b900460ff1615611de25760405162461bcd60e51b8152600401610cbf9061500c565b600754600b543391906000808080611dfb878787612f27565b6001600160a01b038b1660009081526008602090815260408083208d9055600c82528083208c9055600a8252808320859055600e909152902081905592965090945092509050611e4e87858585856131b9565b6001600160a01b0389166000908152600960209081526040808320600d835281842094909455939092556015909152204290558751895114611ea25760405162461bcd60e51b8152600401610cbf90614f7c565b60008080805b8c51811015612267578c8181518110611ebd57fe5b602002602001015193506000805160206151e68339815191526001600160a01b0316846001600160a01b03161480611f1157506001600160a01b03841673b72b31907c1c95f3650b64b2469e08edacee5e8f145b80611f3857506001600160a01b0384167318240bd9c07fa6156ce3f3f61921cc82b2619157145b80611f5957506001600160a01b038416600080516020615246833981519152145b80611f8057506001600160a01b03841673e26a220a341eaca116bda64cf9d5638a935ae629145b611f9c5760405162461bcd60e51b8152600401610cbf90614fbc565b8b8181518110611fa857fe5b6020908102919091018101516001600160a01b038616600090815260048352604080822033835290935291909120549093509150821580611fe7575081155b15611ff15761225f565b81831115611ffd578192505b60006001600160a01b0385166000805160206152468339815191521461202457600061202d565b61202d3361278f565b6001600160a01b03861660008181526004602090815260408083203384528252808320898903905583835260039091529020805487900390559091506000805160206151e683398151915214801561210557506040516370a0823160e01b815284906000805160206151e6833981519152906370a08231906120b3903090600401614e83565b60206040518083038186803b1580156120cb57600080fd5b505afa1580156120df573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061210391908101906149b6565b105b156121725773b72b31907c1c95f3650b64b2469e08edacee5e8f6001600160a01b0316634e71d92d6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561215957600080fd5b505af115801561216d573d6000803e3d6000fd5b505050505b6001600160a01b03851660008051602061524683398151915214156121ee5761219a84613d8a565b6040805180820182526000805160206152268339815191525481526020808201848152336000908152602183528481206000805160206152a683398151915282529092529290209051815590516001909101555b6122086001600160a01b038616338663ffffffff613f2416565b336001600160a01b0316856001600160a01b0316336001600160a01b03167f2cbcd809a4c90d11f8d12c4b6d09986b255ae1e68f54f076c145fbb2185904e187604051612255919061503c565b60405180910390a4505b600101611ea8565b50505050505050505050505050565b6000818152601e602090815260408083208151608081018352815481526001820154938101939093526002810154918301919091526003015460608201526116c19084906135a7565b6122c76119e7565b6122e35760405162461bcd60e51b8152600401610cbf90614fdc565b68056bc75e2d6310000081111561230c5760405162461bcd60e51b8152600401610cbf90614f9c565b601855565b6123196119e7565b6123355760405162461bcd60e51b8152600401610cbf90614fdc565b601d80546001600160a01b0319166001600160a01b0392909216919091179055565b73dac17f958d2ee523a2206206994597c13d831ec781565b600154600160a01b900460ff16156123995760405162461bcd60e51b8152600401610cbf9061500c565b600754600b5433919060008080806123b2878787612f27565b6001600160a01b038b1660009081526008602090815260408083208d9055600c82528083208c9055600a8252808320859055600e90915290208190559296509094509250905061240587858585856131b9565b6001600160a01b0389166000908152600960209081526040808320600d8352818420949094559390925560159091522042905587518951146124595760405162461bcd60e51b8152600401610cbf90614f7c565b600080805b8b51811015612781578b818151811061247357fe5b602002602001015192506000805160206151e68339815191526001600160a01b0316836001600160a01b031614806124c757506001600160a01b03831673b72b31907c1c95f3650b64b2469e08edacee5e8f145b806124ee57506001600160a01b0383167318240bd9c07fa6156ce3f3f61921cc82b2619157145b8061250f57506001600160a01b038316600080516020615246833981519152145b61252b5760405162461bcd60e51b8152600401610cbf90614fbc565b8a818151811061253757fe5b60200260200101519150816000141561254f57612779565b60006001600160a01b0384166000805160206152468339815191521461257657600061257f565b61257f3361278f565b6001600160a01b03851660009081526004602090815260408083203384529091529020549091506125b6908463ffffffff613c1416565b6001600160a01b0385166000818152600460209081526040808320338452825280832094909455918152600390915220546125f7908463ffffffff613c1416565b6001600160a01b0385166000818152600360205260409020919091556126259033308663ffffffff613f7d16565b6001600160a01b0384166000805160206152468339815191521415612722576040516370a0823160e01b81526126ce90600080516020615246833981519152906370a0823190612679903090600401614e83565b60206040518083038186803b15801561269157600080fd5b505afa1580156126a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506126c991908101906149b6565b613fa7565b6040805180820182526000805160206152268339815191525481526020808201848152336000908152602183528481206000805160206152a683398151915282529092529290209051815590516001909101555b336001600160a01b0316846001600160a01b0316336001600160a01b03167fc5017594d2723c038bb216e5bcef3ac65910ade839c0e63253bf5b59efbf0fd78660405161276f919061503c565b60405180910390a4505b60010161245e565b505050505050505050505050565b60405163065509bb60e21b8152600090819073c2edad668740f1aa35e4d8f227fb8e17dca888cd9063195426ec906127ce9060bc90309060040161504a565b60206040518083038186803b1580156127e657600080fd5b505afa1580156127fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061281e91908101906149b6565b90506116c16000805160206152a683398151915284610b3d60008051602061524683398151915287611937565b60185481565b6060601c8054806020026020016040519081016040528092919081815260200182805480156128a957602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161288b575b5050505050905090565b6128bb6119e7565b6128d75760405162461bcd60e51b8152600401610cbf90614fdc565b60405163095ea7b360e01b815273ba100000625a3754423978a60c9317c58a424e3d9063095ea7b390610ff09085908590600401614ee2565b62f099c081565b670de0b6b3a764000081565b6016602052816000526040600020818154811061293c57fe5b6000918252602090912001546001600160a01b03169150829050565b736b175474e89094c44da98b954eedeac495271d0f81565b600154600090600160a01b900460ff161561299d5760405162461bcd60e51b8152600401610cbf9061500c565b600754600b5433919060008080806129b6878787612f27565b6001600160a01b038b1660009081526008602090815260408083208d9055600c82528083208c9055600a8252808320859055600e909152902081905592965090945092509050612a0987858585856131b9565b6001600160a01b0389166000908152600960209081526040808320600d83528184209490945593909255601590915220429055612a44614068565b9750336001600160a01b03167f34fcbac0073d7c3d388e51312faf357774904998eeb8fca628b9e6f65ee1cbf760008a604051611181929190614f1d565b60408051600480825260a0820190925260609160208201608080388339505060408051600480825260a082019092529293506060929150602082016080803883390190505090507318240bd9c07fa6156ce3f3f61921cc82b261915782600081518110612aeb57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505060008051602061524683398151915282600181518110612b2757fe5b60200260200101906001600160a01b031690816001600160a01b03168152505073b72b31907c1c95f3650b64b2469e08edacee5e8f82600281518110612b6957fe5b60200260200101906001600160a01b031690816001600160a01b0316815250506000805160206151e683398151915282600381518110612ba557fe5b60200260200101906001600160a01b031690816001600160a01b03168152505060001981600081518110612bd557fe5b60200260200101818152505060001981600181518110612bf157fe5b60200260200101818152505060001981600281518110612c0d57fe5b60200260200101818152505060001981600381518110612c2957fe5b602002602001018181525050612c3f8282611db8565b612c49600061378a565b5050505050565b60075481565b600f5473b72b31907c1c95f3650b64b2469e08edacee5e8f600090815260036020527ffcfc5d57a009157202436965eb7c01b14f1b51f705a3b4f08296120160c5e109549091612cba91670de0b6b3a764000091610a33919063ffffffff6132be16565b6000805160206151e6833981519152600052600360205260008051602061528683398151915254909150612cf4908263ffffffff613c1416565b6010547318240bd9c07fa6156ce3f3f61921cc82b261915760005260036020527f91de0462b01273d0819ee89d2f822b745d4b4dcc3d05d8e0d13f841abd34e4a254919250612d67918391611483916e111b0ec57e6499a1f4b1014d3f6d5960321b91610a33919063ffffffff6132be16565b60115460008051602061524683398151915260005260036020527f5874759844300eef58e66fc939769d35d274b05b8c5e2a1c60e48b24299f35b654919250612dca91839161148391670de0b6b3a764000091610a33919063ffffffff6132be16565b905090565b612dd76119e7565b612df35760405162461bcd60e51b8152600401610cbf90614fdc565b612dfc8161411e565b50565b6000805160206151e683398151915281565b600154600160a01b900460ff1615612e3b5760405162461bcd60e51b8152600401610cbf9061500c565b81151580612e4857508015155b1561104457612e57828261419f565b8115612ee6576040516323b872dd60e01b81526000805160206151e6833981519152906323b872dd90612e9290339030908790600401614e91565b602060405180830381600087803b158015612eac57600080fd5b505af1158015612ec0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612ee4919081019061495c565b505b8015611044576040516323b872dd60e01b8152736c3f90f043a72fa612cbac8115ee7e52bde6e490906323b872dd90610ff090339030908690600401614e91565b6001600160a01b0383166000908152600860205260408120548190819081908190612f5990889063ffffffff61333a16565b6001600160a01b0389166000908152600c602052604081205491925090612f8790889063ffffffff61333a16565b6001600160a01b038a16600090815260096020908152604080832054600d835281842054600a845282852054600e9094529190932054929950975095509350905081151580612fd557508015155b156131ae576000806000806000612feb8e611382565b9092509050613000828863ffffffff6132be16565b6a0c097ce7bc90715b34b9f160241b9004945061301d858c613c14565b9a5061302f828763ffffffff6132be16565b6a0c097ce7bc90715b34b9f160241b9004945061304c858b613c14565b9950801580159061305c57508615155b156130f957613071818863ffffffff6132be16565b6a0c097ce7bc90715b34b9f160241b9004945061308e8986613c14565b6001600160a01b038f16600090815260156020526040812054919a509093506130c7906a0c097ce7bc90715b34b9f160241b9085611624565b93506130d9858563ffffffff6132be16565b6a0c097ce7bc90715b34b9f160241b900494506130f68b86613c14565b9a505b801580159061310757508515155b156131a85761311c818763ffffffff6132be16565b6a0c097ce7bc90715b34b9f160241b900494506131398886613c14565b975082613178576001600160a01b038e166000908152601560205260408120549350613175906a0c097ce7bc90715b34b9f160241b9085611624565b93505b613188858563ffffffff6132be16565b6a0c097ce7bc90715b34b9f160241b900494506131a58a86613c14565b99505b50505050505b505093509350935093565b6001600160a01b03851660009081526015602052604081205481904281146132b0576000806131f76a0c097ce7bc90715b34b9f160241b8442611624565b90508615613228576132216a0c097ce7bc90715b34b9f160241b610a33898463ffffffff6132be16565b9889019891505b8515613257576132506a0c097ce7bc90715b34b9f160241b610a33888463ffffffff6132be16565b9788019791505b6001600160a01b038a166000908152600080516020615266833981519152602052604090205480156132ac576132a56a0c097ce7bc90715b34b9f160241b610a33838563ffffffff6132be16565b998a019992505b5050505b509496939550929350505050565b6000826132cd57506000610da5565b828202828482816132da57fe5b04146116c15760405162461bcd60e51b8152600401610cbf90614fac565b60006116c183836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614276565b60006116c183836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506142a3565b6001600160a01b038416600090815260208052604081205481906133a6908463ffffffff613c1416565b9050806133b7576000915050613459565b836133c6576000915050613459565b6133ce614580565b506001600160a01b038086166000908152602160209081526040808320938a168352928152908290208251808401909352805480845260019091015491830191909152613454906134439064e8d4a5100090610a3390899061343790889063ffffffff61333a16565b9063ffffffff6132be16565b60208301519063ffffffff613c1416565b925050505b949350505050565b6134696144f9565b6040518060800160405280600142038152602001613485613c4f565b81526040516370a0823160e01b81526020909101906000805160206151e6833981519152906370a08231906134cc9060008051602061524683398151915290600401614e83565b60206040518083038186803b1580156134e457600080fd5b505afa1580156134f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061351c91908101906149b6565b81526020016000805160206152468339815191526001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561356857600080fd5b505afa15801561357c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506135a091908101906149b6565b9052905090565b6001600160a01b038216600090815260156020526040812054825115806135d2575082516000190181115b156135e1576000915050610da5565b6001600160a01b03841660009081526000805160206152668339815191526020526040902054801561366f576136576b02dfafa4e0948fa071940000610a3361363c6b02dfafa4e0948fa07194000060008960000151611624565b84906b02dfafa4e0948fa0719400000363ffffffff6132be16565b925061366c8361148383858860000151611624565b92505b6001600160a01b038516600090815260096020908152604080832054600080516020615206833981519152909252909120546136b091859161148391613c14565b6020808601516001600160a01b03881660009081527fe09f1b989ce5e55474fdfb6ab6036e5e02e6f44d8729816a39308c55c71b13c7909252604090912054919450613720918591611483916e111b0ec57e6499a1f4b1014d3f6d5960321b91610a33919063ffffffff6132be16565b60608501516001600160a01b03871660009081527f064d7c8613d225af78bbf2a77ee533cb03ae723d97d3a14f96452520f45833f26020526040908190205490870151929550613781928692611483929091610a339163ffffffff6132be16565b95945050505050565b600080600061379884613954565b92506137a2614068565b91506137ac613b0b565b9050336001600160a01b03167f34fcbac0073d7c3d388e51312faf357774904998eeb8fca628b9e6f65ee1cbf784846040516137e9929190615080565b60405180910390a28015613842576040516000805160206152a68339815191529033907f24bce930431f78244a70aacbe370a3d06e5fd605a0bb737db20457a7f593e5d09061383990859061503c565b60405180910390a35b9193909250565b60006001600160a01b0383166000805160206152a68339815191521461386f578261387f565b6000805160206152468339815191525b6001600160a01b038116600090815260036020526040902054909150806138b85760405162461bcd60e51b8152600401610cbf90614f5c565b6138f86138d482610a338664e8d4a5100063ffffffff6132be16565b6001600160a01b03861660009081526020805260409020549063ffffffff613c1416565b6001600160a01b03851660008181526020805260409081902092909255905133907f0ec162440d54eb15069478f467bd7294f3d5cead39c9724ff287893483d7c60c9061394690879061503c565b60405180910390a350505050565b336000908152600960205260409020548015610bdf5733600090815260096020526040812055811561398f5761398a33826142cf565b610bdf565b6040516370a0823160e01b815281906000805160206151e6833981519152906370a08231906139c2903090600401614e83565b60206040518083038186803b1580156139da57600080fd5b505afa1580156139ee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250613a1291908101906149b6565b1015613a805773b72b31907c1c95f3650b64b2469e08edacee5e8f6001600160a01b0316634e71d92d6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015613a6757600080fd5b505af1158015613a7b573d6000803e3d6000fd5b505050505b60405163a9059cbb60e01b81526000805160206151e68339815191529063a9059cbb90613ab39033908590600401614eb9565b602060405180830381600087803b158015613acd57600080fd5b505af1158015613ae1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250613b05919081019061495c565b50919050565b60003381613b2760008051602061524683398151915283611937565b905080613b395760009250505061122d565b6040516370a0823160e01b8152613b6e90600080516020615246833981519152906370a0823190612679903090600401614e83565b6000613b8b6000805160206152a68339815191528484600061337c565b604080518082018252600080516020615226833981519152548152600060208083018281526001600160a01b0389168352602182528483206000805160206152a6833981519152845290915292902090518155905160019091015590508015613c0d57613c0d6000805160206152a6833981519152848363ffffffff613f2416565b9250505090565b6000828201838110156116c15760405162461bcd60e51b8152600401610cbf90614f4c565b6000818310613c4857816116c1565b5090919050565b6000612dca7318240bd9c07fa6156ce3f3f61921cc82b26191576001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015613ca157600080fd5b505afa158015613cb5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250613cd991908101906149b6565b6040516370a0823160e01b8152610a33906e111b0ec57e6499a1f4b1014d3f6d5960321b906000805160206151e6833981519152906370a0823190613d36907318240bd9c07fa6156ce3f3f61921cc82b261915790600401614e83565b60206040518083038186803b158015613d4e57600080fd5b505afa158015613d62573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061343791908101906149b6565b3390565b6040516370a0823160e01b81526000906000805160206152a6833981519152906370a0823190613dbe903090600401614e83565b60206040518083038186803b158015613dd657600080fd5b505afa158015613dea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250613e0e91908101906149b6565b604051630441a3e760e41b815290915073c2edad668740f1aa35e4d8f227fb8e17dca888cd9063441a3e7090613e4b9060bc908690600401615080565b600060405180830381600087803b158015613e6557600080fd5b505af1158015613e79573d6000803e3d6000fd5b50506040516370a0823160e01b8152600092508391506000805160206152a6833981519152906370a0823190613eb3903090600401614e83565b60206040518083038186803b158015613ecb57600080fd5b505afa158015613edf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250613f0391908101906149b6565b0390508015611042576110426000805160206152a683398151915282613849565b60405161104290849063a9059cbb60e01b90613f469086908690602401614ee2565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526143db565b604051613fa19085906323b872dd60e01b90613f4690879087908790602401614ed4565b50505050565b6040516370a0823160e01b81526000906000805160206152a6833981519152906370a0823190613fdb903090600401614e83565b60206040518083038186803b158015613ff357600080fd5b505afa158015614007573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061402b91908101906149b6565b604051631c57762b60e31b815290915073c2edad668740f1aa35e4d8f227fb8e17dca888cd9063e2bbb15890613e4b9060bc908690600401615080565b336000908152600d6020526040902054801561122d57336000818152600d6020526040808220919091555163a9059cbb60e01b8152736c3f90f043a72fa612cbac8115ee7e52bde6e4909163a9059cbb916140c891908590600401614eb9565b602060405180830381600087803b1580156140e257600080fd5b505af11580156140f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061411a919081019061495c565b5090565b6001600160a01b0381166141445760405162461bcd60e51b8152600401610cbf90614f3c565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6141a7611707565b601155601055600f5560006141ba612c56565b9050806141d95760405162461bcd60e51b8152600401610cbf9061502c565b6007546142029061148383610a33876a0c097ce7bc90715b34b9f160241b63ffffffff6132be16565b600755600b5461422e9061148383610a33866a0c097ce7bc90715b34b9f160241b63ffffffff6132be16565b600b554260145560405133907fc88fd69bfa06d2cb1591f4ddd5ebede37737856a00d499e4f51e60984dc13d36906142699086908690615080565b60405180910390a2505050565b600081836142975760405162461bcd60e51b8152600401610cbf9190614f2b565b5060008385816116bc57fe5b600081848411156142c75760405162461bcd60e51b8152600401610cbf9190614f2b565b505050900390565b6001600160a01b03821660009081526000805160206152068339815191526020526040902054614305908263ffffffff613c1416565b6001600160a01b0383166000908152600080516020615206833981519152602090815260408220929092556000805160206151e683398151915290526003905260008051602061528683398151915254614365908263ffffffff613c1416565b6000805160206151e683398151915260008190526003602052600080516020615286833981519152919091556040516001600160a01b038416919082907fc5017594d2723c038bb216e5bcef3ac65910ade839c0e63253bf5b59efbf0fd7906143cf90869061503c565b60405180910390a45050565b6143ed826001600160a01b03166144c0565b6144095760405162461bcd60e51b8152600401610cbf9061501c565b60006060836001600160a01b0316836040516144259190614e77565b6000604051808303816000865af19150503d8060008114614462576040519150601f19603f3d011682016040523d82523d6000602084013e614467565b606091505b5091509150816144895760405162461bcd60e51b8152600401610cbf90614f6c565b805115613fa157808060200190516144a4919081019061495c565b613fa15760405162461bcd60e51b8152600401610cbf90614ffc565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590613459575050151592915050565b6040518060800160405280600081526020016000815260200160008152602001600081525090565b828054828255906000526020600020908101928215614574579160200282015b828111156145745781546001600160a01b0319166001600160a01b03843516178255602090920191600190910190614541565b5061411a92915061459a565b604051806040016040528060008152602001600081525090565b61122d91905b8082111561411a5780546001600160a01b03191681556001016145a0565b8035610da5816151bf565b60008083601f8401126145db57600080fd5b50813567ffffffffffffffff8111156145f357600080fd5b60208301915083602082028301111561460b57600080fd5b9250929050565b600082601f83011261462357600080fd5b81356146366146318261511c565b6150f5565b9150818183526020840193506020810190508385602084028201111561465b57600080fd5b60005b83811015614687578161467188826145be565b845250602092830192919091019060010161465e565b5050505092915050565b600082601f8301126146a257600080fd5b81356146b06146318261511c565b915081818352602084019350602081019050838560208402820111156146d557600080fd5b60005b8381101561468757816146eb888261475e565b84525060209283019291909101906001016146d8565b8035610da5816151d3565b8051610da5816151d3565b60006040828403121561472957600080fd5b61473360406150f5565b905060006147418484614769565b825250602061475284848301614769565b60208301525092915050565b8035610da5816151dc565b8051610da5816151dc565b60006020828403121561478657600080fd5b6000610da184846145be565b600080604083850312156147a557600080fd5b60006147b185856145be565b92505060206147c2858286016145be565b9150509250929050565b600080604083850312156147df57600080fd5b60006147eb85856145be565b92505060206147c28582860161475e565b6000806020838503121561480f57600080fd5b823567ffffffffffffffff81111561482657600080fd5b614832858286016145c9565b92509250509250929050565b6000806000806000806060878903121561485757600080fd5b863567ffffffffffffffff81111561486e57600080fd5b61487a89828a016145c9565b9650965050602087013567ffffffffffffffff81111561489957600080fd5b6148a589828a016145c9565b9450945050604087013567ffffffffffffffff8111156148c457600080fd5b6148d089828a016145c9565b92509250509295509295509295565b600080604083850312156148f257600080fd5b823567ffffffffffffffff81111561490957600080fd5b61491585828601614612565b925050602083013567ffffffffffffffff81111561493257600080fd5b6147c285828601614691565b60006020828403121561495057600080fd5b6000610da18484614701565b60006020828403121561496e57600080fd5b6000610da1848461470c565b60006040828403121561498c57600080fd5b6000610da18484614717565b6000602082840312156149aa57600080fd5b6000610da1848461475e565b6000602082840312156149c857600080fd5b6000610da18484614769565b600080604083850312156149e757600080fd5b60006147eb858561475e565b600080600060608486031215614a0857600080fd5b6000614a14868661475e565b9350506020614a258682870161475e565b9250506040614a368682870161475e565b9150509250925092565b6000614a4c8383614a63565b505060200190565b614a5d8161516c565b82525050565b614a5d81615150565b6000614a7782615143565b614a818185615147565b9350614a8c8361513d565b8060005b83811015614aba578151614aa48882614a40565b9750614aaf8361513d565b925050600101614a90565b509495945050505050565b614a5d8161515b565b6000614ad982615143565b614ae38185610bdf565b9350614af3818560208601615189565b9290920192915050565b614a5d81615173565b614a5d8161517e565b6000614b1a82615143565b614b248185615147565b9350614b34818560208601615189565b614b3d816151b5565b9093019392505050565b6000614b54602683615147565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181526564647265737360d01b602082015260400192915050565b6000614b9c601b83615147565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b6000614bd5600b83615147565b6a6e6f206465706f7369747360a81b815260200192915050565b6000614bfc602083615147565b7f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815260200192915050565b6000614c35600e83615147565b6d0c6deeadce840dad2e6dac2e8c6d60931b815260200192915050565b6000614c5f600f83615147565b6e70726f706f73616c2065786973747360881b815260200192915050565b6000614c8a600e83615147565b6d0ecc2d8eaca40e8dede40d0d2ced60931b815260200192915050565b6000614cb4602183615147565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f8152607760f81b602082015260400192915050565b6000614cf7600d83615147565b6c34b73b30b634b2103a37b5b2b760991b815260200192915050565b6000614d20600c83615147565b6b1d5b985d5d1a1bdc9a5e995960a21b815260200192915050565b6000614d48602083615147565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572815260200192915050565b6000614d81600d83615147565b6c696e76616c696420706172616d60981b815260200192915050565b6000614daa602a83615147565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e8152691bdd081cdd58d8d9595960b21b602082015260400192915050565b6000614df6600683615147565b651c185d5cd95960d21b815260200192915050565b6000614e18601f83615147565b7f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400815260200192915050565b6000614e51600e83615147565b6d1b9bdd1a1a5b99c81cdd185ad95960921b815260200192915050565b614a5d8161122d565b60006116c18284614ace565b60208101610da58284614a63565b60608101614e9f8286614a54565b614eac6020830185614a63565b6134596040830184614e6e565b60408101614ec78285614a54565b6116c16020830184614e6e565b60608101614e9f8286614a63565b60408101614ec78285614a63565b602080825281016116c18184614a6c565b60208101610da58284614ac5565b60208101610da58284614afd565b60408101614ec78285614b06565b602080825281016116c18184614b0f565b60208082528101610da581614b47565b60208082528101610da581614b8f565b60208082528101610da581614bc8565b60208082528101610da581614bef565b60208082528101610da581614c28565b60208082528101610da581614c52565b60208082528101610da581614c7d565b60208082528101610da581614ca7565b60208082528101610da581614cea565b60208082528101610da581614d13565b60208082528101610da581614d3b565b60208082528101610da581614d74565b60208082528101610da581614d9d565b60208082528101610da581614de9565b60208082528101610da581614e0b565b60208082528101610da581614e44565b60208101610da58284614e6e565b604081016150588285614e6e565b6116c16020830184614a63565b604081016150738285614e6e565b6116c16020830184614b06565b60408101614ec78285614e6e565b6060810161509c8286614e6e565b614eac6020830185614e6e565b60a081016150b78288614e6e565b6150c46020830187614e6e565b6150d16040830186614e6e565b6150de6060830185614e6e565b6150eb6080830184614e6e565b9695505050505050565b60405181810167ffffffffffffffff8111828210171561511457600080fd5b604052919050565b600067ffffffffffffffff82111561513357600080fd5b5060209081020190565b60200190565b5190565b90815260200190565b6000610da582615160565b151590565b6001600160a01b031690565b6000610da5825b6000610da582615150565b6000610da58261122d565b60005b838110156151a457818101518382015260200161518c565b83811115613fa15750506000910152565b601f01601f191690565b6151c881615150565b8114612dfc57600080fd5b6151c88161515b565b6151c88161122d56fe00000000000000000000000056d811088235f11c8920698a204a5010a788f4b31e38d77566003d7f728cfa677ad07e8283e5607bd89a929ee98c93eba1204873675a8c5155222084f79e8afb00e856b9a6c36ac123ccc305a1df3cb58dbf68c8000000000000000000000000a30911e072a0c88d55b5d0a0984b66b0d04569d02ce56405c0c0b7d532a6d76ebaf14a8d190d60f3be61dae6890d68141a9cc6f826822d1429e81ba812c5218f96710c8923c00dbf3bebc27a2dcc3894116216710000000000000000000000006b3595068778dd592e39a122f4f5a5cf09c90fe2a365627a7a72315820e5ca5ac211cc4197c473a7ab9fbd28c69d8a7ad2c02b9b3ffd337b9183bd40ad6c6578706572696d656e74616cf564736f6c63430005110040
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106104c15760003560e01c8063735de9f711610278578063b6d6d88d1161015c578063d85349f7116100ce578063e9fad8ee11610092578063e9fad8ee14610978578063eb0e8d1a14610980578063ef1c243a14610988578063f2fde38b14610990578063f30127a5146109a3578063fc41aa09146109ab576104c1565b8063d85349f714610945578063dae607db1461094d578063db8bb3a114610955578063e0bab4c414610968578063e53b958d14610970576104c1565b8063c54e44eb11610120578063c54e44eb146108e7578063cf86add5146108ef578063cff361e514610902578063d030205114610915578063d3d204311461091d578063d4d83c9614610932576104c1565b8063b6d6d88d14610888578063bcca1e041461089b578063c1159297146108ae578063c1c5dd27146108c1578063c42cf535146108d4576104c1565b80638caaf9e6116101f5578063ab560e10116101b9578063ab560e1014610837578063abbd3ab11461083f578063ad5c464814610852578063b02eba051461085a578063b187bd261461086d578063b293fdc514610875576104c1565b80638caaf9e6146107e15780638da5cb5b146107f45780638f32d59b146107fc5780639674a93114610811578063a5795eba14610824576104c1565b8063863f2e181161023c578063863f2e18146107a357806386be87a6146107ab57806387359ebe146107be57806389a30271146107d157806389ffc781146107d9576104c1565b8063735de9f7146107655780637f3fd8ba1461076d578063802971a61461078057806382a8af151461078857806383e02cd81461079b576104c1565b80633bb20ece116103aa57806355de54681161031c5780635c60da1b116102e05780635c60da1b1461071f5780636305dc2d14610727578063633e94701461073a57806364e39b871461074257806366067a9514610755578063715018a61461075d576104c1565b806355de5468146106d657806357d159c6146106de57806359d99805146106f157806359dcf522146106f95780635c19a95c1461070c576104c1565b8063481153851161036e578063481153851461069b578063499d7f96146106a35780634fb65036146106b657806352fb1c9d146106be57806353a8f1ec146106c6578063547d0738146106ce576104c1565b80633bb20ece146106525780633d0b00241461065a5780633e1755c71461066257806341adca42146106755780634330c26314610688576104c1565b806317a1d012116104435780632194f3a2116104075780632194f3a2146105e75780632a5522af146105ef5780632d06e5bf146106025780632d81a78e1461060a5780632ee1a86e1461062c578063307e85a41461063f576104c1565b806317a1d0121461059a57806319e772c2146105af5780631c9c4408146105b75780631ca97a2d146105bf5780631d3e3955146105d2576104c1565b80630a4d29241161048a5780630a4d2924146105435780630c340a24146105565780630da47e0a1461055e578063135adff6146105715780631514617e14610592576104c1565b80628cc262146104c65780630114a05e146104f3578063011cee361461051357806302baf1b01461052857806302dd19d91461053b575b600080fd5b6104d96104d4366004614774565b6109be565b6040516104ea9594939291906150a9565b60405180910390f35b610506610501366004614774565b610ba1565b6040516104ea919061503c565b61051b610bb3565b6040516104ea9190614e83565b610506610536366004614774565b610bc5565b610506610be4565b6105066105513660046147cc565b610bea565b61051b610c18565b61050661056c366004614774565b610c27565b61058461057f366004614792565b610c39565b6040516104ea929190615080565b610506610c5d565b6105a2610c65565b6040516104ea9190614f0f565b610506610c7d565b610506610c83565b6105066105cd366004614774565b610c89565b6105e56105e0366004614998565b610c9b565b005b61051b610cea565b6105066105fd3660046147cc565b610cf9565b610506610dab565b61061d61061836600461493e565b610dba565b6040516104ea9392919061508e565b6104d961063a366004614774565b610ea8565b6105e561064d366004614998565b610f4c565b610506610f92565b61051b610f98565b6105e56106703660046147cc565b610fb0565b610506610683366004614774565b611048565b610506610696366004614774565b61105a565b61050661106c565b6105066106b1366004614774565b611193565b6105066111a5565b610506611230565b610506611236565b61051b61123c565b6105e5611254565b6105e56106ec36600461493e565b61133a565b61050661137c565b610584610707366004614774565b611382565b61051b61071a366004614774565b6114ff565b61051b61151a565b610506610735366004614774565b611529565b6105a261153a565b6105e5610750366004614774565b611552565b610506611598565b6105e561159e565b6105a261160c565b61050661077b3660046149f3565b611624565b61051b6116c8565b61051b610796366004614998565b6116e0565b61061d611707565b6105e5611800565b6105066107b9366004614792565b61191b565b6105066107cc366004614792565b611937565b61051b611962565b6105a261197a565b6105e56107ef366004614998565b611992565b61051b6119d8565b6108046119e7565b6040516104ea9190614f01565b61050661081f366004614774565b611a0b565b61058461083236600461483e565b611a1d565b61051b611d0c565b61050661084d366004614774565b611d1e565b61051b611d31565b610506610868366004614774565b611d49565b610804611d5b565b6105e56108833660046147fc565b611d6b565b610506610896366004614792565b611d9b565b6105e56108a93660046148df565b611db8565b6105066108bc3660046147cc565b612276565b6105e56108cf366004614998565b6122bf565b6105e56108e2366004614774565b612311565b61051b612357565b6105e56108fd3660046148df565b61236f565b610506610910366004614774565b61278f565b61050661284b565b610925612851565b6040516104ea9190614ef0565b6105e56109403660046147cc565b6128b3565b610506612910565b610506612917565b61051b6109633660046147cc565b612923565b61051b612958565b610506612970565b6105e5612a82565b610506612c50565b610506612c56565b6105e561099e366004614774565b612dcf565b61051b612dff565b6105e56109b93660046149d4565b612e11565b60008060008060006109d586600754600b54612f27565b929750909550935091506109ec86868686866131b9565b90955093506000610a0c6a0c097ce7bc90715b34b9f160241b8242611624565b9050610a4c610a3f6a0c097ce7bc90715b34b9f160241b610a33878563ffffffff6132be16565b9063ffffffff6132f816565b859063ffffffff61333a16565b9350610a80610a736a0c097ce7bc90715b34b9f160241b610a33868563ffffffff6132be16565b849063ffffffff61333a16565b60405163065509bb60e21b815290935060009073c2edad668740f1aa35e4d8f227fb8e17dca888cd9063195426ec90610ac09060bc90309060040161504a565b60206040518083038186803b158015610ad857600080fd5b505afa158015610aec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610b1091908101906149b6565b9050610b946000805160206152a683398151915289610b3d6000805160206152468339815191528c611937565b60008051602061524683398151915260005260036020527f5874759844300eef58e66fc939769d35d274b05b8c5e2a1c60e48b24299f35b654610b8f90610a338764e8d4a5100063ffffffff6132be16565b61337c565b9250505091939590929450565b60086020526000908152604090205481565b60008051602061524683398151915281565b6001600160a01b0381166000908152600360205260409020545b919050565b601b5481565b601f6020528160005260406000208181548110610c0357fe5b90600052602060002001600091509150505481565b601d546001600160a01b031681565b600d6020526000908152604090205481565b60216020908152600092835260408084209091529082529020805460019091015482565b630784ce0081565b73bebc44782c7db0a1a60cb6fe97d0b483032ff1c781565b600f5481565b60105481565b60096020526000908152604090205481565b610ca36119e7565b610cc85760405162461bcd60e51b8152600401610cbf90614fdc565b60405180910390fd5b80610ce55760405162461bcd60e51b8152600401610cbf90614fec565b601a55565b6002546001600160a01b031681565b601d546000906001600160a01b03163314610d265760405162461bcd60e51b8152600401610cbf90614fcc565b6000828152601e602052604090205415610d525760405162461bcd60e51b8152600401610cbf90614f8c565b610d5a6144f9565b610d62613461565b6000848152601e60209081526040918290208351815590830151600182015590820151600282015560608201516003909101559050610da184826135a7565b9150505b92915050565b6a744f570177f475546c000081565b6000806000600160149054906101000a900460ff1615610dec5760405162461bcd60e51b8152600401610cbf9061500c565b600754600b543391906000808080610e05878787612f27565b6001600160a01b038b1660009081526008602090815260408083208d9055600c82528083208c9055600a8252808320859055600e909152902081905592965090945092509050610e5887858585856131b9565b6001600160a01b0389166000908152600960209081526040808320600d83528184209490945593909255601590915220429055610e948b61378a565b995099509950505050505050509193909250565b6000806000806000610ec86000805160206151e683398151915287611937565b610ee67318240bd9c07fa6156ce3f3f61921cc82b261915788611937565b610f0473b72b31907c1c95f3650b64b2469e08edacee5e8f89611937565b610f1c6000805160206152468339815191528a611937565b610f3a73e26a220a341eaca116bda64cf9d5638a935ae6298b611937565b939a9299509097509550909350915050565b610f546119e7565b610f705760405162461bcd60e51b8152600401610cbf90614fdc565b80610f8d5760405162461bcd60e51b8152600401610cbf90614fec565b601b55565b600b5481565b73e26a220a341eaca116bda64cf9d5638a935ae62981565b801561104457610fc08282613849565b6040516323b872dd60e01b81526001600160a01b038316906323b872dd90610ff090339030908690600401614e91565b602060405180830381600087803b15801561100a57600080fd5b505af115801561101e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611042919081019061495c565b505b5050565b600e6020526000908152604090205481565b600a6020526000908152604090205481565b600154600090600160a01b900460ff16156110995760405162461bcd60e51b8152600401610cbf9061500c565b600754600b5433919060008080806110b2878787612f27565b6001600160a01b038b1660009081526008602090815260408083208d9055600c82528083208c9055600a8252808320859055600e90915290208190559296509094509250905061110587858585856131b9565b6001600160a01b0389166000908152600960209081526040808320600d83528184209490945593909255601590915290812042905561114390613954565b9750336001600160a01b03167f34fcbac0073d7c3d388e51312faf357774904998eeb8fca628b9e6f65ee1cbf7896000604051611181929190615065565b60405180910390a25050505050505090565b60176020526000908152604090205481565b600154600090600160a01b900460ff16156111d25760405162461bcd60e51b8152600401610cbf9061500c565b6111da613b0b565b9050801561122d576040516000805160206152a68339815191529033907f24bce930431f78244a70aacbe370a3d06e5fd605a0bb737db20457a7f593e5d09061122490859061503c565b60405180910390a35b90565b60115481565b601a5481565b73b72b31907c1c95f3650b64b2469e08edacee5e8f81565b61125c6119e7565b6112785760405162461bcd60e51b8152600401610cbf90614fdc565b6000805160206152a6833981519152600052601f6020527ff671d343b5ca683fae72ab8c7c043b684239026f02f343b9b49b7056b624a83854806112bc5750611338565b6000805160206152a6833981519152600052601f6020527ff671d343b5ca683fae72ab8c7c043b684239026f02f343b9b49b7056b624a8388054600019830190811061130457fe5b60009182526020808320909101546000805160206152a6833981519152909252805260008051602061522683398151915255505b565b6113426119e7565b61135e5760405162461bcd60e51b8152600401610cbf90614fdc565b60018054911515600160a01b0260ff60a01b19909216919091179055565b60195481565b6001600160a01b03811660009081526000805160206152668339815191526020526040812054819080156113f957600f546001600160a01b038516600090815260008051602061526683398151915260205260409020546113f691670de0b6b3a764000091610a339163ffffffff6132be16565b91505b506001600160a01b038316600090815260008051602061520683398151915260209081526040808320547fe09f1b989ce5e55474fdfb6ab6036e5e02e6f44d8729816a39308c55c71b13c79092529091205490925080156114925761148f836114836e111b0ec57e6499a1f4b1014d3f6d5960321b610a33601054866132be90919063ffffffff16565b9063ffffffff613c1416565b92505b506001600160a01b03831660009081527f064d7c8613d225af78bbf2a77ee533cb03ae723d97d3a14f96452520f45833f2602052604090205480156114f9576114f683611483670de0b6b3a7640000610a33601154866132be90919063ffffffff16565b92505b50915091565b6005602052600090815260409020546001600160a01b031681565b6001546001600160a01b031681565b602080526000908152604090205481565b73d8ee69652e4e4838f2531732a46d1f7f584f0b7f81565b61155a6119e7565b6115765760405162461bcd60e51b8152600401610cbf90614fdc565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b60145481565b6115a66119e7565b6115c25760405162461bcd60e51b8152600401610cbf90614fdc565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b73d9e1ce17f2641f24ae83637ab66a2cca9c378b9f81565b6000611636824263ffffffff613c3916565b9150828211156116c157635ffd02a082111580611657575063669136e08310155b15611664575060006116c1565b635ffd02a083101561167857635ffd02a092505b63669136e082111561168c5763669136e091505b600061169e838563ffffffff61333a16565b905063069434406116b5868363ffffffff6132be16565b816116bc57fe5b049150505b9392505050565b7318240bd9c07fa6156ce3f3f61921cc82b261915781565b601c81815481106116ed57fe5b6000918252602090912001546001600160a01b0316905081565b6000806000806117256b02dfafa4e0948fa071940000600042611624565b90506117576b02dfafa4e0948fa071940000610a33836b02dfafa4e0948fa07194000003670de0b6b3a76400006132be565b9350611761613c4f565b60008051602061524683398151915260005260036020527f5874759844300eef58e66fc939769d35d274b05b8c5e2a1c60e48b24299f35b65490935080156117f9576000805160206151e683398151915260005260036020526000805160206152868339815191525482036a744f570177f475546c0000016117f582610a3383670de0b6b3a764000063ffffffff6132be16565b9350505b5050909192565b6118086119e7565b6118245760405162461bcd60e51b8152600401610cbf90614fdc565b6040516393f1a40b60e01b815273c2edad668740f1aa35e4d8f227fb8e17dca888cd9060009082906393f1a40b906118639060bc90309060040161504a565b604080518083038186803b15801561187a57600080fd5b505afa15801561188e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506118b2919081019061497a565b51604051630441a3e760e41b81529091506001600160a01b0383169063441a3e70906118e59060bc908590600401615080565b600060405180830381600087803b1580156118ff57600080fd5b505af1158015611913573d6000803e3d6000fd5b505050505050565b6000806119288484611937565b9050610da1848483600061337c565b6001600160a01b03918216600090815260046020908152604080832093909416825291909152205490565b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b736c3f90f043a72fa612cbac8115ee7e52bde6e49081565b61199a6119e7565b6119b65760405162461bcd60e51b8152600401610cbf90614fdc565b806119d35760405162461bcd60e51b8152600401610cbf90614fec565b601955565b6000546001600160a01b031690565b600080546001600160a01b03166119fc613d86565b6001600160a01b031614905090565b60156020526000908152604090205481565b6001546000908190600160a01b900460ff1615611a4c5760405162461bcd60e51b8152600401610cbf9061500c565b8685148015611a5a57508683145b611a765760405162461bcd60e51b8152600401610cbf90614f7c565b60005b87811015611bdc57611ae2878783818110611a9057fe5b90506020020135600960008c8c86818110611aa757fe5b9050602002016020611abc9190810190614774565b6001600160a01b031681526020810191909152604001600020549063ffffffff613c1416565b600960008b8b85818110611af257fe5b9050602002016020611b079190810190614774565b6001600160a01b03168152602081019190915260400160002055611b46878783818110611b3057fe5b9050602002013584613c1490919063ffffffff16565b9250611b6e858583818110611b5757fe5b90506020020135600d60008c8c86818110611aa757fe5b600d60008b8b85818110611b7e57fe5b9050602002016020611b939190810190614774565b6001600160a01b03168152602081019190915260400160002055611bd2858583818110611bbc57fe5b9050602002013583613c1490919063ffffffff16565b9150600101611a79565b508115611c6c576040516323b872dd60e01b81526000805160206151e6833981519152906323b872dd90611c1890339030908790600401614e91565b602060405180830381600087803b158015611c3257600080fd5b505af1158015611c46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611c6a919081019061495c565b505b8015611d01576040516323b872dd60e01b8152736c3f90f043a72fa612cbac8115ee7e52bde6e490906323b872dd90611cad90339030908690600401614e91565b602060405180830381600087803b158015611cc757600080fd5b505af1158015611cdb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611cff919081019061495c565b505b965096945050505050565b6000805160206152a683398151915281565b6000610da582611d2c613461565b6135a7565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b600c6020526000908152604090205481565b600154600160a01b900460ff1681565b611d736119e7565b611d8f5760405162461bcd60e51b8152600401610cbf90614fdc565b611042601c8383614521565b600660209081526000928352604080842090915290825290205481565b600154600160a01b900460ff1615611de25760405162461bcd60e51b8152600401610cbf9061500c565b600754600b543391906000808080611dfb878787612f27565b6001600160a01b038b1660009081526008602090815260408083208d9055600c82528083208c9055600a8252808320859055600e909152902081905592965090945092509050611e4e87858585856131b9565b6001600160a01b0389166000908152600960209081526040808320600d835281842094909455939092556015909152204290558751895114611ea25760405162461bcd60e51b8152600401610cbf90614f7c565b60008080805b8c51811015612267578c8181518110611ebd57fe5b602002602001015193506000805160206151e68339815191526001600160a01b0316846001600160a01b03161480611f1157506001600160a01b03841673b72b31907c1c95f3650b64b2469e08edacee5e8f145b80611f3857506001600160a01b0384167318240bd9c07fa6156ce3f3f61921cc82b2619157145b80611f5957506001600160a01b038416600080516020615246833981519152145b80611f8057506001600160a01b03841673e26a220a341eaca116bda64cf9d5638a935ae629145b611f9c5760405162461bcd60e51b8152600401610cbf90614fbc565b8b8181518110611fa857fe5b6020908102919091018101516001600160a01b038616600090815260048352604080822033835290935291909120549093509150821580611fe7575081155b15611ff15761225f565b81831115611ffd578192505b60006001600160a01b0385166000805160206152468339815191521461202457600061202d565b61202d3361278f565b6001600160a01b03861660008181526004602090815260408083203384528252808320898903905583835260039091529020805487900390559091506000805160206151e683398151915214801561210557506040516370a0823160e01b815284906000805160206151e6833981519152906370a08231906120b3903090600401614e83565b60206040518083038186803b1580156120cb57600080fd5b505afa1580156120df573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061210391908101906149b6565b105b156121725773b72b31907c1c95f3650b64b2469e08edacee5e8f6001600160a01b0316634e71d92d6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561215957600080fd5b505af115801561216d573d6000803e3d6000fd5b505050505b6001600160a01b03851660008051602061524683398151915214156121ee5761219a84613d8a565b6040805180820182526000805160206152268339815191525481526020808201848152336000908152602183528481206000805160206152a683398151915282529092529290209051815590516001909101555b6122086001600160a01b038616338663ffffffff613f2416565b336001600160a01b0316856001600160a01b0316336001600160a01b03167f2cbcd809a4c90d11f8d12c4b6d09986b255ae1e68f54f076c145fbb2185904e187604051612255919061503c565b60405180910390a4505b600101611ea8565b50505050505050505050505050565b6000818152601e602090815260408083208151608081018352815481526001820154938101939093526002810154918301919091526003015460608201526116c19084906135a7565b6122c76119e7565b6122e35760405162461bcd60e51b8152600401610cbf90614fdc565b68056bc75e2d6310000081111561230c5760405162461bcd60e51b8152600401610cbf90614f9c565b601855565b6123196119e7565b6123355760405162461bcd60e51b8152600401610cbf90614fdc565b601d80546001600160a01b0319166001600160a01b0392909216919091179055565b73dac17f958d2ee523a2206206994597c13d831ec781565b600154600160a01b900460ff16156123995760405162461bcd60e51b8152600401610cbf9061500c565b600754600b5433919060008080806123b2878787612f27565b6001600160a01b038b1660009081526008602090815260408083208d9055600c82528083208c9055600a8252808320859055600e90915290208190559296509094509250905061240587858585856131b9565b6001600160a01b0389166000908152600960209081526040808320600d8352818420949094559390925560159091522042905587518951146124595760405162461bcd60e51b8152600401610cbf90614f7c565b600080805b8b51811015612781578b818151811061247357fe5b602002602001015192506000805160206151e68339815191526001600160a01b0316836001600160a01b031614806124c757506001600160a01b03831673b72b31907c1c95f3650b64b2469e08edacee5e8f145b806124ee57506001600160a01b0383167318240bd9c07fa6156ce3f3f61921cc82b2619157145b8061250f57506001600160a01b038316600080516020615246833981519152145b61252b5760405162461bcd60e51b8152600401610cbf90614fbc565b8a818151811061253757fe5b60200260200101519150816000141561254f57612779565b60006001600160a01b0384166000805160206152468339815191521461257657600061257f565b61257f3361278f565b6001600160a01b03851660009081526004602090815260408083203384529091529020549091506125b6908463ffffffff613c1416565b6001600160a01b0385166000818152600460209081526040808320338452825280832094909455918152600390915220546125f7908463ffffffff613c1416565b6001600160a01b0385166000818152600360205260409020919091556126259033308663ffffffff613f7d16565b6001600160a01b0384166000805160206152468339815191521415612722576040516370a0823160e01b81526126ce90600080516020615246833981519152906370a0823190612679903090600401614e83565b60206040518083038186803b15801561269157600080fd5b505afa1580156126a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506126c991908101906149b6565b613fa7565b6040805180820182526000805160206152268339815191525481526020808201848152336000908152602183528481206000805160206152a683398151915282529092529290209051815590516001909101555b336001600160a01b0316846001600160a01b0316336001600160a01b03167fc5017594d2723c038bb216e5bcef3ac65910ade839c0e63253bf5b59efbf0fd78660405161276f919061503c565b60405180910390a4505b60010161245e565b505050505050505050505050565b60405163065509bb60e21b8152600090819073c2edad668740f1aa35e4d8f227fb8e17dca888cd9063195426ec906127ce9060bc90309060040161504a565b60206040518083038186803b1580156127e657600080fd5b505afa1580156127fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061281e91908101906149b6565b90506116c16000805160206152a683398151915284610b3d60008051602061524683398151915287611937565b60185481565b6060601c8054806020026020016040519081016040528092919081815260200182805480156128a957602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161288b575b5050505050905090565b6128bb6119e7565b6128d75760405162461bcd60e51b8152600401610cbf90614fdc565b60405163095ea7b360e01b815273ba100000625a3754423978a60c9317c58a424e3d9063095ea7b390610ff09085908590600401614ee2565b62f099c081565b670de0b6b3a764000081565b6016602052816000526040600020818154811061293c57fe5b6000918252602090912001546001600160a01b03169150829050565b736b175474e89094c44da98b954eedeac495271d0f81565b600154600090600160a01b900460ff161561299d5760405162461bcd60e51b8152600401610cbf9061500c565b600754600b5433919060008080806129b6878787612f27565b6001600160a01b038b1660009081526008602090815260408083208d9055600c82528083208c9055600a8252808320859055600e909152902081905592965090945092509050612a0987858585856131b9565b6001600160a01b0389166000908152600960209081526040808320600d83528184209490945593909255601590915220429055612a44614068565b9750336001600160a01b03167f34fcbac0073d7c3d388e51312faf357774904998eeb8fca628b9e6f65ee1cbf760008a604051611181929190614f1d565b60408051600480825260a0820190925260609160208201608080388339505060408051600480825260a082019092529293506060929150602082016080803883390190505090507318240bd9c07fa6156ce3f3f61921cc82b261915782600081518110612aeb57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505060008051602061524683398151915282600181518110612b2757fe5b60200260200101906001600160a01b031690816001600160a01b03168152505073b72b31907c1c95f3650b64b2469e08edacee5e8f82600281518110612b6957fe5b60200260200101906001600160a01b031690816001600160a01b0316815250506000805160206151e683398151915282600381518110612ba557fe5b60200260200101906001600160a01b031690816001600160a01b03168152505060001981600081518110612bd557fe5b60200260200101818152505060001981600181518110612bf157fe5b60200260200101818152505060001981600281518110612c0d57fe5b60200260200101818152505060001981600381518110612c2957fe5b602002602001018181525050612c3f8282611db8565b612c49600061378a565b5050505050565b60075481565b600f5473b72b31907c1c95f3650b64b2469e08edacee5e8f600090815260036020527ffcfc5d57a009157202436965eb7c01b14f1b51f705a3b4f08296120160c5e109549091612cba91670de0b6b3a764000091610a33919063ffffffff6132be16565b6000805160206151e6833981519152600052600360205260008051602061528683398151915254909150612cf4908263ffffffff613c1416565b6010547318240bd9c07fa6156ce3f3f61921cc82b261915760005260036020527f91de0462b01273d0819ee89d2f822b745d4b4dcc3d05d8e0d13f841abd34e4a254919250612d67918391611483916e111b0ec57e6499a1f4b1014d3f6d5960321b91610a33919063ffffffff6132be16565b60115460008051602061524683398151915260005260036020527f5874759844300eef58e66fc939769d35d274b05b8c5e2a1c60e48b24299f35b654919250612dca91839161148391670de0b6b3a764000091610a33919063ffffffff6132be16565b905090565b612dd76119e7565b612df35760405162461bcd60e51b8152600401610cbf90614fdc565b612dfc8161411e565b50565b6000805160206151e683398151915281565b600154600160a01b900460ff1615612e3b5760405162461bcd60e51b8152600401610cbf9061500c565b81151580612e4857508015155b1561104457612e57828261419f565b8115612ee6576040516323b872dd60e01b81526000805160206151e6833981519152906323b872dd90612e9290339030908790600401614e91565b602060405180830381600087803b158015612eac57600080fd5b505af1158015612ec0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612ee4919081019061495c565b505b8015611044576040516323b872dd60e01b8152736c3f90f043a72fa612cbac8115ee7e52bde6e490906323b872dd90610ff090339030908690600401614e91565b6001600160a01b0383166000908152600860205260408120548190819081908190612f5990889063ffffffff61333a16565b6001600160a01b0389166000908152600c602052604081205491925090612f8790889063ffffffff61333a16565b6001600160a01b038a16600090815260096020908152604080832054600d835281842054600a845282852054600e9094529190932054929950975095509350905081151580612fd557508015155b156131ae576000806000806000612feb8e611382565b9092509050613000828863ffffffff6132be16565b6a0c097ce7bc90715b34b9f160241b9004945061301d858c613c14565b9a5061302f828763ffffffff6132be16565b6a0c097ce7bc90715b34b9f160241b9004945061304c858b613c14565b9950801580159061305c57508615155b156130f957613071818863ffffffff6132be16565b6a0c097ce7bc90715b34b9f160241b9004945061308e8986613c14565b6001600160a01b038f16600090815260156020526040812054919a509093506130c7906a0c097ce7bc90715b34b9f160241b9085611624565b93506130d9858563ffffffff6132be16565b6a0c097ce7bc90715b34b9f160241b900494506130f68b86613c14565b9a505b801580159061310757508515155b156131a85761311c818763ffffffff6132be16565b6a0c097ce7bc90715b34b9f160241b900494506131398886613c14565b975082613178576001600160a01b038e166000908152601560205260408120549350613175906a0c097ce7bc90715b34b9f160241b9085611624565b93505b613188858563ffffffff6132be16565b6a0c097ce7bc90715b34b9f160241b900494506131a58a86613c14565b99505b50505050505b505093509350935093565b6001600160a01b03851660009081526015602052604081205481904281146132b0576000806131f76a0c097ce7bc90715b34b9f160241b8442611624565b90508615613228576132216a0c097ce7bc90715b34b9f160241b610a33898463ffffffff6132be16565b9889019891505b8515613257576132506a0c097ce7bc90715b34b9f160241b610a33888463ffffffff6132be16565b9788019791505b6001600160a01b038a166000908152600080516020615266833981519152602052604090205480156132ac576132a56a0c097ce7bc90715b34b9f160241b610a33838563ffffffff6132be16565b998a019992505b5050505b509496939550929350505050565b6000826132cd57506000610da5565b828202828482816132da57fe5b04146116c15760405162461bcd60e51b8152600401610cbf90614fac565b60006116c183836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614276565b60006116c183836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506142a3565b6001600160a01b038416600090815260208052604081205481906133a6908463ffffffff613c1416565b9050806133b7576000915050613459565b836133c6576000915050613459565b6133ce614580565b506001600160a01b038086166000908152602160209081526040808320938a168352928152908290208251808401909352805480845260019091015491830191909152613454906134439064e8d4a5100090610a3390899061343790889063ffffffff61333a16565b9063ffffffff6132be16565b60208301519063ffffffff613c1416565b925050505b949350505050565b6134696144f9565b6040518060800160405280600142038152602001613485613c4f565b81526040516370a0823160e01b81526020909101906000805160206151e6833981519152906370a08231906134cc9060008051602061524683398151915290600401614e83565b60206040518083038186803b1580156134e457600080fd5b505afa1580156134f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061351c91908101906149b6565b81526020016000805160206152468339815191526001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561356857600080fd5b505afa15801561357c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506135a091908101906149b6565b9052905090565b6001600160a01b038216600090815260156020526040812054825115806135d2575082516000190181115b156135e1576000915050610da5565b6001600160a01b03841660009081526000805160206152668339815191526020526040902054801561366f576136576b02dfafa4e0948fa071940000610a3361363c6b02dfafa4e0948fa07194000060008960000151611624565b84906b02dfafa4e0948fa0719400000363ffffffff6132be16565b925061366c8361148383858860000151611624565b92505b6001600160a01b038516600090815260096020908152604080832054600080516020615206833981519152909252909120546136b091859161148391613c14565b6020808601516001600160a01b03881660009081527fe09f1b989ce5e55474fdfb6ab6036e5e02e6f44d8729816a39308c55c71b13c7909252604090912054919450613720918591611483916e111b0ec57e6499a1f4b1014d3f6d5960321b91610a33919063ffffffff6132be16565b60608501516001600160a01b03871660009081527f064d7c8613d225af78bbf2a77ee533cb03ae723d97d3a14f96452520f45833f26020526040908190205490870151929550613781928692611483929091610a339163ffffffff6132be16565b95945050505050565b600080600061379884613954565b92506137a2614068565b91506137ac613b0b565b9050336001600160a01b03167f34fcbac0073d7c3d388e51312faf357774904998eeb8fca628b9e6f65ee1cbf784846040516137e9929190615080565b60405180910390a28015613842576040516000805160206152a68339815191529033907f24bce930431f78244a70aacbe370a3d06e5fd605a0bb737db20457a7f593e5d09061383990859061503c565b60405180910390a35b9193909250565b60006001600160a01b0383166000805160206152a68339815191521461386f578261387f565b6000805160206152468339815191525b6001600160a01b038116600090815260036020526040902054909150806138b85760405162461bcd60e51b8152600401610cbf90614f5c565b6138f86138d482610a338664e8d4a5100063ffffffff6132be16565b6001600160a01b03861660009081526020805260409020549063ffffffff613c1416565b6001600160a01b03851660008181526020805260409081902092909255905133907f0ec162440d54eb15069478f467bd7294f3d5cead39c9724ff287893483d7c60c9061394690879061503c565b60405180910390a350505050565b336000908152600960205260409020548015610bdf5733600090815260096020526040812055811561398f5761398a33826142cf565b610bdf565b6040516370a0823160e01b815281906000805160206151e6833981519152906370a08231906139c2903090600401614e83565b60206040518083038186803b1580156139da57600080fd5b505afa1580156139ee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250613a1291908101906149b6565b1015613a805773b72b31907c1c95f3650b64b2469e08edacee5e8f6001600160a01b0316634e71d92d6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015613a6757600080fd5b505af1158015613a7b573d6000803e3d6000fd5b505050505b60405163a9059cbb60e01b81526000805160206151e68339815191529063a9059cbb90613ab39033908590600401614eb9565b602060405180830381600087803b158015613acd57600080fd5b505af1158015613ae1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250613b05919081019061495c565b50919050565b60003381613b2760008051602061524683398151915283611937565b905080613b395760009250505061122d565b6040516370a0823160e01b8152613b6e90600080516020615246833981519152906370a0823190612679903090600401614e83565b6000613b8b6000805160206152a68339815191528484600061337c565b604080518082018252600080516020615226833981519152548152600060208083018281526001600160a01b0389168352602182528483206000805160206152a6833981519152845290915292902090518155905160019091015590508015613c0d57613c0d6000805160206152a6833981519152848363ffffffff613f2416565b9250505090565b6000828201838110156116c15760405162461bcd60e51b8152600401610cbf90614f4c565b6000818310613c4857816116c1565b5090919050565b6000612dca7318240bd9c07fa6156ce3f3f61921cc82b26191576001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015613ca157600080fd5b505afa158015613cb5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250613cd991908101906149b6565b6040516370a0823160e01b8152610a33906e111b0ec57e6499a1f4b1014d3f6d5960321b906000805160206151e6833981519152906370a0823190613d36907318240bd9c07fa6156ce3f3f61921cc82b261915790600401614e83565b60206040518083038186803b158015613d4e57600080fd5b505afa158015613d62573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061343791908101906149b6565b3390565b6040516370a0823160e01b81526000906000805160206152a6833981519152906370a0823190613dbe903090600401614e83565b60206040518083038186803b158015613dd657600080fd5b505afa158015613dea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250613e0e91908101906149b6565b604051630441a3e760e41b815290915073c2edad668740f1aa35e4d8f227fb8e17dca888cd9063441a3e7090613e4b9060bc908690600401615080565b600060405180830381600087803b158015613e6557600080fd5b505af1158015613e79573d6000803e3d6000fd5b50506040516370a0823160e01b8152600092508391506000805160206152a6833981519152906370a0823190613eb3903090600401614e83565b60206040518083038186803b158015613ecb57600080fd5b505afa158015613edf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250613f0391908101906149b6565b0390508015611042576110426000805160206152a683398151915282613849565b60405161104290849063a9059cbb60e01b90613f469086908690602401614ee2565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526143db565b604051613fa19085906323b872dd60e01b90613f4690879087908790602401614ed4565b50505050565b6040516370a0823160e01b81526000906000805160206152a6833981519152906370a0823190613fdb903090600401614e83565b60206040518083038186803b158015613ff357600080fd5b505afa158015614007573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061402b91908101906149b6565b604051631c57762b60e31b815290915073c2edad668740f1aa35e4d8f227fb8e17dca888cd9063e2bbb15890613e4b9060bc908690600401615080565b336000908152600d6020526040902054801561122d57336000818152600d6020526040808220919091555163a9059cbb60e01b8152736c3f90f043a72fa612cbac8115ee7e52bde6e4909163a9059cbb916140c891908590600401614eb9565b602060405180830381600087803b1580156140e257600080fd5b505af11580156140f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061411a919081019061495c565b5090565b6001600160a01b0381166141445760405162461bcd60e51b8152600401610cbf90614f3c565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6141a7611707565b601155601055600f5560006141ba612c56565b9050806141d95760405162461bcd60e51b8152600401610cbf9061502c565b6007546142029061148383610a33876a0c097ce7bc90715b34b9f160241b63ffffffff6132be16565b600755600b5461422e9061148383610a33866a0c097ce7bc90715b34b9f160241b63ffffffff6132be16565b600b554260145560405133907fc88fd69bfa06d2cb1591f4ddd5ebede37737856a00d499e4f51e60984dc13d36906142699086908690615080565b60405180910390a2505050565b600081836142975760405162461bcd60e51b8152600401610cbf9190614f2b565b5060008385816116bc57fe5b600081848411156142c75760405162461bcd60e51b8152600401610cbf9190614f2b565b505050900390565b6001600160a01b03821660009081526000805160206152068339815191526020526040902054614305908263ffffffff613c1416565b6001600160a01b0383166000908152600080516020615206833981519152602090815260408220929092556000805160206151e683398151915290526003905260008051602061528683398151915254614365908263ffffffff613c1416565b6000805160206151e683398151915260008190526003602052600080516020615286833981519152919091556040516001600160a01b038416919082907fc5017594d2723c038bb216e5bcef3ac65910ade839c0e63253bf5b59efbf0fd7906143cf90869061503c565b60405180910390a45050565b6143ed826001600160a01b03166144c0565b6144095760405162461bcd60e51b8152600401610cbf9061501c565b60006060836001600160a01b0316836040516144259190614e77565b6000604051808303816000865af19150503d8060008114614462576040519150601f19603f3d011682016040523d82523d6000602084013e614467565b606091505b5091509150816144895760405162461bcd60e51b8152600401610cbf90614f6c565b805115613fa157808060200190516144a4919081019061495c565b613fa15760405162461bcd60e51b8152600401610cbf90614ffc565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590613459575050151592915050565b6040518060800160405280600081526020016000815260200160008152602001600081525090565b828054828255906000526020600020908101928215614574579160200282015b828111156145745781546001600160a01b0319166001600160a01b03843516178255602090920191600190910190614541565b5061411a92915061459a565b604051806040016040528060008152602001600081525090565b61122d91905b8082111561411a5780546001600160a01b03191681556001016145a0565b8035610da5816151bf565b60008083601f8401126145db57600080fd5b50813567ffffffffffffffff8111156145f357600080fd5b60208301915083602082028301111561460b57600080fd5b9250929050565b600082601f83011261462357600080fd5b81356146366146318261511c565b6150f5565b9150818183526020840193506020810190508385602084028201111561465b57600080fd5b60005b83811015614687578161467188826145be565b845250602092830192919091019060010161465e565b5050505092915050565b600082601f8301126146a257600080fd5b81356146b06146318261511c565b915081818352602084019350602081019050838560208402820111156146d557600080fd5b60005b8381101561468757816146eb888261475e565b84525060209283019291909101906001016146d8565b8035610da5816151d3565b8051610da5816151d3565b60006040828403121561472957600080fd5b61473360406150f5565b905060006147418484614769565b825250602061475284848301614769565b60208301525092915050565b8035610da5816151dc565b8051610da5816151dc565b60006020828403121561478657600080fd5b6000610da184846145be565b600080604083850312156147a557600080fd5b60006147b185856145be565b92505060206147c2858286016145be565b9150509250929050565b600080604083850312156147df57600080fd5b60006147eb85856145be565b92505060206147c28582860161475e565b6000806020838503121561480f57600080fd5b823567ffffffffffffffff81111561482657600080fd5b614832858286016145c9565b92509250509250929050565b6000806000806000806060878903121561485757600080fd5b863567ffffffffffffffff81111561486e57600080fd5b61487a89828a016145c9565b9650965050602087013567ffffffffffffffff81111561489957600080fd5b6148a589828a016145c9565b9450945050604087013567ffffffffffffffff8111156148c457600080fd5b6148d089828a016145c9565b92509250509295509295509295565b600080604083850312156148f257600080fd5b823567ffffffffffffffff81111561490957600080fd5b61491585828601614612565b925050602083013567ffffffffffffffff81111561493257600080fd5b6147c285828601614691565b60006020828403121561495057600080fd5b6000610da18484614701565b60006020828403121561496e57600080fd5b6000610da1848461470c565b60006040828403121561498c57600080fd5b6000610da18484614717565b6000602082840312156149aa57600080fd5b6000610da1848461475e565b6000602082840312156149c857600080fd5b6000610da18484614769565b600080604083850312156149e757600080fd5b60006147eb858561475e565b600080600060608486031215614a0857600080fd5b6000614a14868661475e565b9350506020614a258682870161475e565b9250506040614a368682870161475e565b9150509250925092565b6000614a4c8383614a63565b505060200190565b614a5d8161516c565b82525050565b614a5d81615150565b6000614a7782615143565b614a818185615147565b9350614a8c8361513d565b8060005b83811015614aba578151614aa48882614a40565b9750614aaf8361513d565b925050600101614a90565b509495945050505050565b614a5d8161515b565b6000614ad982615143565b614ae38185610bdf565b9350614af3818560208601615189565b9290920192915050565b614a5d81615173565b614a5d8161517e565b6000614b1a82615143565b614b248185615147565b9350614b34818560208601615189565b614b3d816151b5565b9093019392505050565b6000614b54602683615147565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181526564647265737360d01b602082015260400192915050565b6000614b9c601b83615147565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b6000614bd5600b83615147565b6a6e6f206465706f7369747360a81b815260200192915050565b6000614bfc602083615147565b7f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815260200192915050565b6000614c35600e83615147565b6d0c6deeadce840dad2e6dac2e8c6d60931b815260200192915050565b6000614c5f600f83615147565b6e70726f706f73616c2065786973747360881b815260200192915050565b6000614c8a600e83615147565b6d0ecc2d8eaca40e8dede40d0d2ced60931b815260200192915050565b6000614cb4602183615147565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f8152607760f81b602082015260400192915050565b6000614cf7600d83615147565b6c34b73b30b634b2103a37b5b2b760991b815260200192915050565b6000614d20600c83615147565b6b1d5b985d5d1a1bdc9a5e995960a21b815260200192915050565b6000614d48602083615147565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572815260200192915050565b6000614d81600d83615147565b6c696e76616c696420706172616d60981b815260200192915050565b6000614daa602a83615147565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e8152691bdd081cdd58d8d9595960b21b602082015260400192915050565b6000614df6600683615147565b651c185d5cd95960d21b815260200192915050565b6000614e18601f83615147565b7f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400815260200192915050565b6000614e51600e83615147565b6d1b9bdd1a1a5b99c81cdd185ad95960921b815260200192915050565b614a5d8161122d565b60006116c18284614ace565b60208101610da58284614a63565b60608101614e9f8286614a54565b614eac6020830185614a63565b6134596040830184614e6e565b60408101614ec78285614a54565b6116c16020830184614e6e565b60608101614e9f8286614a63565b60408101614ec78285614a63565b602080825281016116c18184614a6c565b60208101610da58284614ac5565b60208101610da58284614afd565b60408101614ec78285614b06565b602080825281016116c18184614b0f565b60208082528101610da581614b47565b60208082528101610da581614b8f565b60208082528101610da581614bc8565b60208082528101610da581614bef565b60208082528101610da581614c28565b60208082528101610da581614c52565b60208082528101610da581614c7d565b60208082528101610da581614ca7565b60208082528101610da581614cea565b60208082528101610da581614d13565b60208082528101610da581614d3b565b60208082528101610da581614d74565b60208082528101610da581614d9d565b60208082528101610da581614de9565b60208082528101610da581614e0b565b60208082528101610da581614e44565b60208101610da58284614e6e565b604081016150588285614e6e565b6116c16020830184614a63565b604081016150738285614e6e565b6116c16020830184614b06565b60408101614ec78285614e6e565b6060810161509c8286614e6e565b614eac6020830185614e6e565b60a081016150b78288614e6e565b6150c46020830187614e6e565b6150d16040830186614e6e565b6150de6060830185614e6e565b6150eb6080830184614e6e565b9695505050505050565b60405181810167ffffffffffffffff8111828210171561511457600080fd5b604052919050565b600067ffffffffffffffff82111561513357600080fd5b5060209081020190565b60200190565b5190565b90815260200190565b6000610da582615160565b151590565b6001600160a01b031690565b6000610da5825b6000610da582615150565b6000610da58261122d565b60005b838110156151a457818101518382015260200161518c565b83811115613fa15750506000910152565b601f01601f191690565b6151c881615150565b8114612dfc57600080fd5b6151c88161515b565b6151c88161122d56fe00000000000000000000000056d811088235f11c8920698a204a5010a788f4b31e38d77566003d7f728cfa677ad07e8283e5607bd89a929ee98c93eba1204873675a8c5155222084f79e8afb00e856b9a6c36ac123ccc305a1df3cb58dbf68c8000000000000000000000000a30911e072a0c88d55b5d0a0984b66b0d04569d02ce56405c0c0b7d532a6d76ebaf14a8d190d60f3be61dae6890d68141a9cc6f826822d1429e81ba812c5218f96710c8923c00dbf3bebc27a2dcc3894116216710000000000000000000000006b3595068778dd592e39a122f4f5a5cf09c90fe2a365627a7a72315820e5ca5ac211cc4197c473a7ab9fbd28c69d8a7ad2c02b9b3ffd337b9183bd40ad6c6578706572696d656e74616cf564736f6c63430005110040
Deployed Bytecode Sourcemap
71243:32283:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;71243:32283:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84029:1620;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;69355:58;;;;;;;;;:::i;:::-;;;;;;;;65048:76;;;:::i;:::-;;;;;;;;96439:170;;;;;;;;;:::i;70554:40::-;;;:::i;70901:53::-;;;;;;;;;:::i;70805:23::-;;;:::i;69811:52::-;;;;;;;;;:::i;71138:97::-;;;;;;;;;:::i;:::-;;;;;;;;;66145:64;;;:::i;65867:96::-;;;:::i;:::-;;;;;;;;70017:32;;;:::i;70056:::-;;;:::i;69457:46::-;;;;;;;;;:::i;102526:242::-;;;;;;;;;:::i;:::-;;68843:26;;;:::i;98824:453::-;;;;;;;;;:::i;68668:79::-;;;:::i;78286:265::-;;;;;;;;;:::i;:::-;;;;;;;;;;94903:579;;;;;;;;;:::i;102776:237::-;;;;;;;;;:::i;69663:39::-;;;:::i;65144:79::-;;;:::i;92775:228::-;;;;;;;;;:::i;69913:52::-;;;;;;;;;:::i;69559:46::-;;;;;;;;;:::i;78559:307::-;;;:::i;70355:49::-;;;;;;;;;:::i;79202:287::-;;;:::i;70095:34::-;;;:::i;70505:42::-;;;:::i;64886:74::-;;;:::i;103021:280::-;;;:::i;101468:128::-;;;;;;;;;:::i;70454:44::-;;;:::i;95490:941::-;;;;;;;;;:::i;69097:43::-;;;;;;;;;:::i;68443:29::-;;;:::i;71001:53::-;;;;;;;;;:::i;65970:75::-;;;:::i;101604:143::-;;;;;;;;;:::i;70201:33::-;;;:::i;59757:140::-;;;:::i;65738:109::-;;;:::i;97189:1146::-;;;;;;;;;:::i;64967:74::-;;;:::i;70603:33::-;;;;;;;;;:::i;93454:998::-;;;:::i;73209:336::-;;;:::i;72224:256::-;;;;;;;;;:::i;94686:209::-;;;;;;;;;:::i;65495:73::-;;;:::i;65242:85::-;;;:::i;102266:252::-;;;;;;;;;:::i;58946:79::-;;;:::i;59312:94::-;;;:::i;:::-;;;;;;;;70243:50;;;;;;;;;:::i;90396:1027::-;;;;;;;;;:::i;65655:74::-;;;:::i;98616:200::-;;;;;;;;;:::i;65336:73::-;;;:::i;69709:64::-;;;;;;;;;:::i;68814:20::-;;;:::i;101894:145::-;;;;;;;;;:::i;69202:72::-;;;;;;;;;:::i;76201:2077::-;;;;;;;;;:::i;98375:233::-;;;;;;;;;:::i;102047:211::-;;;;;;;;;:::i;101755:131::-;;;;;;;;;:::i;65575:73::-;;;:::i;74531:1662::-;;;;;;;;;:::i;71753:463::-;;;;;;;;;:::i;70411:36::-;;;:::i;71535:146::-;;;:::i;:::-;;;;;;;;103309:214;;;;;;;;;:::i;66054:63::-;;;:::i;66874:47::-;;;:::i;70302:46::-;;;;;;;;;:::i;65416:72::-;;;:::i;78874:320::-;;;:::i;82420:531::-;;;:::i;69315:33::-;;;:::i;96617:564::-;;;:::i;60052:109::-;;;;;;;;;:::i;64806:73::-;;;:::i;91491:507::-;;;;;;;;;:::i;84029:1620::-;84122:25;84149:31;84182:26;84210:32;84244:26;84381:112;84403:7;84425:18;;84458:24;;84381:7;:112::i;:::-;84288:205;;-1:-1:-1;84288:205:0;;-1:-1:-1;84288:205:0;-1:-1:-1;84288:205:0;-1:-1:-1;84553:187:0;84580:7;84288:205;;;;84553:12;:187::i;:::-;84506:234;;-1:-1:-1;84506:234:0;-1:-1:-1;84807:18:0;84828:98;-1:-1:-1;;;84807:18:0;84900:15;84828:22;:98::i;:::-;84807:119;-1:-1:-1;84958:132:0;84995:80;-1:-1:-1;;;84995:52:0;:18;84807:119;84995:52;:40;:52;:::i;:::-;:74;:80;:74;:80;:::i;:::-;84958:18;;:132;:36;:132;:::i;:::-;84937:153;-1:-1:-1;85128:144:0;85171:86;-1:-1:-1;;;85171:58:0;:24;85218:10;85171:58;:46;:58;:::i;:86::-;85128:24;;:144;:42;:144;:::i;:::-;85308:107;;-1:-1:-1;;;85308:107:0;;85101:171;;-1:-1:-1;85285:20:0;;66754:42;;85308:61;;:107;;66862:3;;85409:4;;85308:107;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;85308:107:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;85308:107:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;85308:107:0;;;;;;;;;85285:130;;85449:192;-1:-1:-1;;;;;;;;;;;85502:7:0;85524:34;-1:-1:-1;;;;;;;;;;;85550:7:0;85524:16;:34::i;:::-;-1:-1:-1;;;;;;;;;;;85600:29:0;;:20;:29;;;;85573:57;;:22;:12;85590:4;85573:22;:16;:22;:::i;:57::-;85449:18;:192::i;:::-;85428:213;;84029:1620;;;;;;;;;:::o;69355:58::-;;;;;;;;;;;;;:::o;65048:76::-;-1:-1:-1;;;;;;;;;;;65048:76:0;:::o;96439:170::-;-1:-1:-1;;;;;96574:27:0;;96542:7;96574:27;;;:20;:27;;;;;;96439:170;;;;:::o;70554:40::-;;;;:::o;70901:53::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;70805:23::-;;;-1:-1:-1;;;;;70805:23:0;;:::o;69811:52::-;;;;;;;;;;;;;:::o;71138:97::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;66145:64::-;66200:9;66145:64;:::o;65867:96::-;65920:42;65867:96;:::o;70017:32::-;;;;:::o;70056:::-;;;;:::o;69457:46::-;;;;;;;;;;;;;:::o;102526:242::-;59158:9;:7;:9::i;:::-;59150:54;;;;-1:-1:-1;;;59150:54:0;;;;;;;;;;;;;;;;;102661:26;102653:52;;;;-1:-1:-1;;;102653:52:0;;;;;;;;;102716:20;:44;102526:242::o;68843:26::-;;;-1:-1:-1;;;;;68843:26:0;;:::o;98824:453::-;98987:8;;98940:7;;-1:-1:-1;;;;;98987:8:0;98973:10;:22;98965:47;;;;-1:-1:-1;;;98965:47:0;;;;;;;;;99031:26;;;;:14;:26;;;;;:39;:44;99023:72;;;;-1:-1:-1;;;99023:72:0;;;;;;;;;99106:32;;:::i;:::-;99141:19;:17;:19::i;:::-;99171:26;;;;:14;:26;;;;;;;;;:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;99106:54;-1:-1:-1;99231:38:0;99248:7;99106:54;99231:16;:38::i;:::-;99224:45;;;98824:453;;;;;:::o;68668:79::-;68719:28;68668:79;:::o;78286:265::-;78416:25;78443:31;78477:26;71488:8;;;;;;;;;;;71487:9;71479:28;;;;-1:-1:-1;;;71479:28:0;;;;;;;;;83040:18;;83105:24;;78386:10;;83040:18;83010:27;;;;83267:114;78386:10;83040:18;83105:24;83267:7;:114::i;:::-;-1:-1:-1;;;;;83392:32:0;;;;;;:23;:32;;;;;;;;:54;;;83457:29;:38;;;;;:66;;;83588:11;:20;;;;;:41;;;83640:17;:26;;;;;:53;;;83142:239;;-1:-1:-1;83142:239:0;;-1:-1:-1;83142:239:0;-1:-1:-1;83142:239:0;-1:-1:-1;83759:187:0;83416:7;83142:239;;;;83759:12;:187::i;:::-;-1:-1:-1;;;;;83707:20:0;;;;;;:11;:20;;;;;;;;83729:17;:26;;;;;83706:240;;;;;;;;83957:15;:24;;;;83984:15;83957:42;;78528:15;78535:7;78528:6;:15::i;:::-;78521:22;;;;;;71518:1;;;;;;;78286:265;;;;;:::o;94903:579::-;95021:19;95055:20;95090;95125:22;95162:25;95237:31;-1:-1:-1;;;;;;;;;;;95260:7:0;95237:16;:31::i;:::-;95283:32;64999:42;95307:7;95283:16;:32::i;:::-;95330;64918:42;95354:7;95330:16;:32::i;:::-;95377:34;-1:-1:-1;;;;;;;;;;;95403:7:0;95377:16;:34::i;:::-;95426:37;65181:42;95455:7;95426:16;:37::i;:::-;95215:259;;;;-1:-1:-1;95215:259:0;;-1:-1:-1;95215:259:0;-1:-1:-1;95215:259:0;;-1:-1:-1;94903:579:0;-1:-1:-1;;94903:579:0:o;102776:237::-;59158:9;:7;:9::i;:::-;59150:54;;;;-1:-1:-1;;;59150:54:0;;;;;;;;;102909:25;102901:51;;;;-1:-1:-1;;;102901:51:0;;;;;;;;;102963:19;:42;102776:237::o;69663:39::-;;;;:::o;65144:79::-;65181:42;65144:79;:::o;92775:228::-;92851:11;;92847:149;;92879:29;92894:5;92901:6;92879:14;:29::i;:::-;92923:61;;-1:-1:-1;;;92923:61:0;;-1:-1:-1;;;;;92923:26:0;;;;;:61;;92950:10;;92970:4;;92977:6;;92923:61;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;92923:61:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;92923:61:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;92923:61:0;;;;;;;;;;92847:149;92775:228;;:::o;69913:52::-;;;;;;;;;;;;;:::o;69559:46::-;;;;;;;;;;;;;:::o;78559:307::-;71488:8;;78671:25;;-1:-1:-1;;;71488:8:0;;;;71487:9;71479:28;;;;-1:-1:-1;;;71479:28:0;;;;;;;;;83040:18;;83105:24;;78641:10;;83040:18;83010:27;;;;83267:114;78641:10;83040:18;83105:24;83267:7;:114::i;:::-;-1:-1:-1;;;;;83392:32:0;;;;;;:23;:32;;;;;;;;:54;;;83457:29;:38;;;;;:66;;;83588:11;:20;;;;;:41;;;83640:17;:26;;;;;:53;;;83142:239;;-1:-1:-1;83142:239:0;;-1:-1:-1;83142:239:0;-1:-1:-1;83142:239:0;-1:-1:-1;83759:187:0;83416:7;83142:239;;;;83759:12;:187::i;:::-;-1:-1:-1;;;;;83707:20:0;;;;;;:11;:20;;;;;;;;83729:17;:26;;;;;83706:240;;;;;;;;83957:15;:24;;;;;;83984:15;83957:42;;78734:17;;:10;:17::i;:::-;78714:37;;78789:10;-1:-1:-1;;;;;78769:89:0;;78814:17;78846:1;78769:89;;;;;;;;;;;;;;;;71518:1;;;;;;;78559:307;:::o;70355:49::-;;;;;;;;;;;;;:::o;79202:287::-;71488:8;;79280:26;;-1:-1:-1;;;71488:8:0;;;;71487:9;71479:28;;;;-1:-1:-1;;;71479:28:0;;;;;;;;;79345:13;:11;:13::i;:::-;79324:34;-1:-1:-1;79372:23:0;;79369:113;;79416:54;;-1:-1:-1;;;;;;;;;;;65687:42:0;79432:10;;79416:54;;;;79451:18;;79416:54;;;;;;;;;;79369:113;79202:287;:::o;70095:34::-;;;;:::o;70505:42::-;;;;:::o;64886:74::-;64918:42;64886:74;:::o;103021:280::-;59158:9;:7;:9::i;:::-;59150:54;;;;-1:-1:-1;;;59150:54:0;;;;;;;;;-1:-1:-1;;;;;;;;;;;103114:13:0;103130:23;:16;:23;;;:30;103174:10;103171:48;;103201:7;;;103171:48;-1:-1:-1;;;;;;;;;;;103259:23:0;;:16;:23;;;:34;;-1:-1:-1;;103283:9:0;;;103259:34;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;103231:25:0;;;;;-1:-1:-1;;;;;;;;;;;103231:62:0;-1:-1:-1;59215:1:0;103021:280::o;101468:128::-;59158:9;:7;:9::i;:::-;59150:54;;;;-1:-1:-1;;;59150:54:0;;;;;;;;;101568:8;:20;;;;;-1:-1:-1;;;101568:20:0;-1:-1:-1;;;;101568:20:0;;;;;;;;;101468:128::o;70454:44::-;;;;:::o;95490:941::-;-1:-1:-1;;;;;95671:33:0;;95590:21;95671:33;;;-1:-1:-1;;;;;;;;;;;95671:24:0;:33;:24;:33;;;95590:21;;95719:12;;95715:164;;95821:17;;-1:-1:-1;;;;;95765:33:0;;:24;:33;;;-1:-1:-1;;;;;;;;;;;95765:24:0;:33;:24;:33;;;:102;;95862:4;;95765:74;;;:55;:74;:::i;:102::-;95748:119;;95715:164;-1:-1:-1;;;;;;95907:32:0;;:23;:32;;;-1:-1:-1;;;;;;;;;;;95907:23:0;:32;;;:23;:32;;;;95962:24;:33;;;;;;;95907:32;;-1:-1:-1;96010:12:0;;96006:174;;96055:113;96154:13;96055:76;-1:-1:-1;;;96055:48:0;96085:17;;96055:7;:29;;:48;;;;:::i;:76::-;:98;:113;:98;:113;:::i;:::-;96039:129;;96006:174;-1:-1:-1;;;;;;96202:35:0;;:26;:35;;;:26;;:35;:26;:35;;;96252:12;;96248:176;;96297:115;96398:13;96297:78;96370:4;96297:50;96327:19;;96297:7;:29;;:50;;;;:::i;:115::-;96281:131;;96248:176;95490:941;;;;:::o;69097:43::-;;;;;;;;;;;;-1:-1:-1;;;;;69097:43:0;;:::o;68443:29::-;;;-1:-1:-1;;;;;68443:29:0;;:::o;71001:53::-;;;;;;;;;;;;;:::o;65970:75::-;66002:42;65970:75;:::o;101604:143::-;59158:9;:7;:9::i;:::-;59150:54;;;;-1:-1:-1;;;59150:54:0;;;;;;;;;101713:11;:26;;-1:-1:-1;;;;;;101713:26:0;-1:-1:-1;;;;;101713:26:0;;;;;;;;;;101604:143::o;70201:33::-;;;;:::o;59757:140::-;59158:9;:7;:9::i;:::-;59150:54;;;;-1:-1:-1;;;59150:54:0;;;;;;;;;59856:1;59840:6;;59819:40;;-1:-1:-1;;;;;59840:6:0;;;;59819:40;;59856:1;;59819:40;59887:1;59870:19;;-1:-1:-1;;;;;;59870:19:0;;;59757:140::o;65738:109::-;65804:42;65738:109;:::o;97189:1146::-;97363:14;97412:38;:14;97434:15;97412:38;:21;:38;:::i;:::-;97395:55;;97482:10;97465:14;:27;97461:867;;;66468:37;97513:39;;;;:93;;-1:-1:-1;66567:39:0;97573:33;;;97513:93;97509:264;;;-1:-1:-1;97756:1:0;97749:8;;97509:264;66468:37;97791:34;;97787:167;;;66468:37;;-1:-1:-1;97787:167:0;66567:39;97972:36;;97968:167;;;66567:39;;-1:-1:-1;97968:167:0;98151:22;98176:30;:14;98195:10;98176:30;:18;:30;:::i;:::-;98151:55;-1:-1:-1;66290:9:0;98230:32;:12;98151:55;98230:32;:16;:32;:::i;:::-;:60;;;;;;98221:69;;97461:867;;97189:1146;;;;;:::o;64967:74::-;64999:42;64967:74;:::o;70603:33::-;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;70603:33:0;;-1:-1:-1;70603:33:0;:::o;93454:998::-;93532:19;93553;93574:21;93613:19;93635:115;66668:12;93708:1;93724:15;93635:22;:115::i;:::-;93613:137;;93777:121;66668:12;93777:55;93814:11;66668:12;93790:35;93827:4;93777:12;:55::i;:121::-;93763:135;;93925:18;:16;:18::i;:::-;-1:-1:-1;;;;;;;;;;;93956:21:0;93980:29;:20;:29;;;;93911:32;;-1:-1:-1;94024:18:0;;94020:425;;-1:-1:-1;;;;;;;;;;;94177:31:0;94286:26;:20;:26;;-1:-1:-1;;;;;;;;;;;94286:26:0;94211:101;;68719:28;94211:101;94345:88;94419:13;94345:51;94211:101;94391:4;94345:51;:45;:51;:::i;:88::-;94329:104;;94020:425;;93454:998;;;;;:::o;73209:336::-;59158:9;:7;:9::i;:::-;59150:54;;;;-1:-1:-1;;;59150:54:0;;;;;;;;;73370:59;;-1:-1:-1;;;73370:59:0;;66754:42;;73283:21;;66754:42;;73370:13;;:59;;66862:3;;73423:4;;73370:59;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;73370:59:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;73370:59:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;73370:59:0;;;;;;;;;:66;73447:90;;-1:-1:-1;;;73447:90:0;;73370:66;;-1:-1:-1;;;;;;73447:13:0;;;;;:90;;66862:3;;73370:66;;73447:90;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;73447:90:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;73447:90:0;;;;59215:1;;73209:336::o;72224:256::-;72331:7;72356:18;72377:30;72394:5;72401;72377:16;:30::i;:::-;72356:51;;72425:47;72444:5;72451;72458:10;72470:1;72425:18;:47::i;94686:209::-;-1:-1:-1;;;;;94854:24:0;;;94811:15;94854:24;;;:17;:24;;;;;;;;:33;;;;;;;;;;;;;94686:209::o;65495:73::-;65526:42;65495:73;:::o;65242:85::-;65284:42;65242:85;:::o;102266:252::-;59158:9;:7;:9::i;:::-;59150:54;;;;-1:-1:-1;;;59150:54:0;;;;;;;;;102405:28;102397:54;;;;-1:-1:-1;;;102397:54:0;;;;;;;;;102462:22;:48;102266:252::o;58946:79::-;58984:7;59011:6;-1:-1:-1;;;;;59011:6:0;58946:79;:::o;59312:94::-;59352:4;59392:6;;-1:-1:-1;;;;;59392:6:0;59376:12;:10;:12::i;:::-;-1:-1:-1;;;;;59376:22:0;;59369:29;;59312:94;:::o;70243:50::-;;;;;;;;;;;;;:::o;90396:1027::-;71488:8;;90605:17;;;;-1:-1:-1;;;71488:8:0;;;;71487:9;71479:28;;;;-1:-1:-1;;;71479:28:0;;;;;;;;;90673:37;;;:84;;;;-1:-1:-1;90714:43:0;;;90673:84;90665:111;;;;-1:-1:-1;;;90665:111:0;;;;;;;;;90794:9;90789:378;90809:19;;;90789:378;;;90877:44;90906:11;;90918:1;90906:14;;;;;;;;;;;;;90877:11;:24;90889:8;;90898:1;90889:11;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;90877:24:0;;;;;;;;;;;;-1:-1:-1;90877:24:0;;;:44;:28;:44;:::i;:::-;90850:11;:24;90862:8;;90871:1;90862:11;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;90850:24:0;;;;;;;;;;;;-1:-1:-1;90850:24:0;:71;90948:29;90962:11;;90974:1;90962:14;;;;;;;;;;;;;90948:9;:13;;:29;;;;:::i;:::-;90936:41;;91025:56;91060:17;;91078:1;91060:20;;;;;;;;;;;;;91025:17;:30;91043:8;;91052:1;91043:11;;;;;;91025:56;90992:17;:30;91010:8;;91019:1;91010:11;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;90992:30:0;;;;;;;;;;;;-1:-1:-1;90992:30:0;:89;91114:41;91134:17;;91152:1;91134:20;;;;;;;;;;;;;91114:15;:19;;:41;;;;:::i;:::-;91096:59;-1:-1:-1;90830:3:0;;90789:378;;;-1:-1:-1;91181:14:0;;91177:110;;91212:63;;-1:-1:-1;;;91212:63:0;;-1:-1:-1;;;;;;;;;;;64837:42:0;91212:25;;:63;;91238:10;;91258:4;;91265:9;;91212:63;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;91212:63:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;91212:63:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;91212:63:0;;;;;;;;;;91177:110;91301:20;;91297:119;;91338:66;;-1:-1:-1;;;91338:66:0;;65284:42;;91338:22;;:66;;91361:10;;91381:4;;91388:15;;91338:66;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;91338:66:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;91338:66:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;91338:66:0;;;;;;;;;;91297:119;90396:1027;;;;;;;;;:::o;65655:74::-;-1:-1:-1;;;;;;;;;;;65655:74:0;:::o;98616:200::-;98719:18;98762:46;98779:7;98788:19;:17;:19::i;:::-;98762:16;:46::i;65336:73::-;65367:42;65336:73;:::o;69709:64::-;;;;;;;;;;;;;:::o;68814:20::-;;;-1:-1:-1;;;68814:20:0;;;;;:::o;101894:145::-;59158:9;:7;:9::i;:::-;59150:54;;;;-1:-1:-1;;;59150:54:0;;;;;;;;;102006:25;:16;102025:6;;102006:25;:::i;69202:72::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;76201:2077::-;71488:8;;-1:-1:-1;;;71488:8:0;;;;71487:9;71479:28;;;;-1:-1:-1;;;71479:28:0;;;;;;;;;83040:18;;83105:24;;76352:10;;83040:18;83010:27;;;;83267:114;76352:10;83040:18;83105:24;83267:7;:114::i;:::-;-1:-1:-1;;;;;83392:32:0;;;;;;:23;:32;;;;;;;;:54;;;83457:29;:38;;;;;:66;;;83588:11;:20;;;;;:41;;;83640:17;:26;;;;;:53;;;83142:239;;-1:-1:-1;83142:239:0;;-1:-1:-1;83142:239:0;-1:-1:-1;83142:239:0;-1:-1:-1;83759:187:0;83416:7;83142:239;;;;83759:12;:187::i;:::-;-1:-1:-1;;;;;83707:20:0;;;;;;:11;:20;;;;;;;;83729:17;:26;;;;;83706:240;;;;;;;;83957:15;:24;;;;83984:15;83957:42;;76405:13;;76388;;:30;76380:57;;;;-1:-1:-1;;;76380:57:0;;;;;;;;;76450:13;;;;76539:1732;76563:6;:13;76559:1;:17;76539:1732;;;76606:6;76613:1;76606:9;;;;;;;;;;;;;;76598:17;;-1:-1:-1;;;;;;;;;;;;;;;;76638:13:0;:5;-1:-1:-1;;;;;76638:13:0;;:31;;;-1:-1:-1;;;;;;76655:14:0;;64918:42;76655:14;76638:31;:49;;;-1:-1:-1;;;;;;76673:14:0;;64999:42;76673:14;76638:49;:69;;;-1:-1:-1;;;;;;76691:16:0;;-1:-1:-1;;;;;;;;;;;76691:16:0;76638:69;:92;;;-1:-1:-1;;;;;;76711:19:0;;65181:42;76711:19;76638:92;76630:118;;;;-1:-1:-1;;;76630:118:0;;;;;;;;;76781:6;76788:1;76781:9;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;76820:24:0;;;;;;:17;:24;;;;;;76845:10;76820:36;;;;;;;;;;76781:9;;-1:-1:-1;76820:36:0;-1:-1:-1;76875:18:0;;;:39;;-1:-1:-1;76897:17:0;;76875:39;76871:88;;;76935:8;;76871:88;76993:12;76977:13;:28;76973:97;;;77042:12;77026:28;;76973:97;77086:21;-1:-1:-1;;;;;77111:16:0;;-1:-1:-1;;;;;;;;;;;77111:16:0;77110:56;;77165:1;77110:56;;;77131:31;77151:10;77131:19;:31::i;:::-;-1:-1:-1;;;;;77183:24:0;;;;;;:17;:24;;;;;;;;77208:10;77183:36;;;;;;;77222:28;;;77183:67;;77316:27;;;:20;:27;;;;;;;:43;;;77286:73;;77086:80;;-1:-1:-1;;;;;;;;;;;;77401:13:0;:70;;;;-1:-1:-1;77418:37:0;;-1:-1:-1;;;77418:37:0;;77458:13;;-1:-1:-1;;;;;;;;;;;64837:42:0;77418:22;;:37;;77449:4;;77418:37;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;77418:37:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;77418:37:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;77418:37:0;;;;;;;;;:53;77401:70;77397:193;;;64918:42;-1:-1:-1;;;;;77546:26:0;;:28;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;77546:28:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;77546:28:0;;;;77397:193;-1:-1:-1;;;;;77655:16:0;;-1:-1:-1;;;;;;;;;;;77655:16:0;77651:362;;;77692:43;77721:13;77692:28;:43::i;:::-;77800:195;;;;;;;;-1:-1:-1;;;;;;;;;;;77872:25:0;77800:195;;77872:18;77800:195;;;;;;77779:10;-1:-1:-1;77756:34:0;;;:22;:34;;;;;-1:-1:-1;;;;;;;;;;;77756:41:0;;;;;;;;:239;;;;;;;;;;;77651:362;78029:53;-1:-1:-1;;;;;78029:26:0;;78056:10;78068:13;78029:53;:26;:53;:::i;:::-;78183:10;-1:-1:-1;;;;;78104:155:0;78159:5;-1:-1:-1;;;;;78104:155:0;78130:10;-1:-1:-1;;;;;78104:155:0;;78231:13;78104:155;;;;;;;;;;;;;;;76539:1732;;76578:3;;76539:1732;;;;84012:1;;;71518;;;;;;;76201:2077;;:::o;98375:233::-;98504:18;98573:26;;;:14;:26;;;;;;;;98547:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;98564:7;;98547:16;:53::i;102047:211::-;59158:9;:7;:9::i;:::-;59150:54;;;;-1:-1:-1;;;59150:54:0;;;;;;;;;102186:4;102168:14;:22;;102160:49;;;;-1:-1:-1;;;102160:49:0;;;;;;;;;102220:13;:30;102047:211::o;101755:131::-;59158:9;:7;:9::i;:::-;59150:54;;;;-1:-1:-1;;;59150:54:0;;;;;;;;;101858:8;:20;;-1:-1:-1;;;;;;101858:20:0;-1:-1:-1;;;;;101858:20:0;;;;;;;;;;101755:131::o;65575:73::-;65606:42;65575:73;:::o;74531:1662::-;71488:8;;-1:-1:-1;;;71488:8:0;;;;71487:9;71479:28;;;;-1:-1:-1;;;71479:28:0;;;;;;;;;83040:18;;83105:24;;74680:10;;83040:18;83010:27;;;;83267:114;74680:10;83040:18;83105:24;83267:7;:114::i;:::-;-1:-1:-1;;;;;83392:32:0;;;;;;:23;:32;;;;;;;;:54;;;83457:29;:38;;;;;:66;;;83588:11;:20;;;;;:41;;;83640:17;:26;;;;;:53;;;83142:239;;-1:-1:-1;83142:239:0;;-1:-1:-1;83142:239:0;-1:-1:-1;83142:239:0;-1:-1:-1;83759:187:0;83416:7;83142:239;;;;83759:12;:187::i;:::-;-1:-1:-1;;;;;83707:20:0;;;;;;:11;:20;;;;;;;;83729:17;:26;;;;;83706:240;;;;;;;;83957:15;:24;;;;83984:15;83957:42;;74733:13;;74716;;:30;74708:57;;;;-1:-1:-1;;;74708:57:0;;;;;;;;;74778:13;;;74836:1350;74860:6;:13;74856:1;:17;74836:1350;;;74903:6;74910:1;74903:9;;;;;;;;;;;;;;74895:17;;-1:-1:-1;;;;;;;;;;;;;;;;74935:13:0;:5;-1:-1:-1;;;;;74935:13:0;;:31;;;-1:-1:-1;;;;;;74952:14:0;;64918:42;74952:14;74935:31;:49;;;-1:-1:-1;;;;;;74970:14:0;;64999:42;74970:14;74935:49;:69;;;-1:-1:-1;;;;;;74988:16:0;;-1:-1:-1;;;;;;;;;;;74988:16:0;74935:69;74927:95;;;;-1:-1:-1;;;74927:95:0;;;;;;;;;75053:6;75060:1;75053:9;;;;;;;;;;;;;;75039:23;;75081:11;75096:1;75081:16;75077:65;;;75118:8;;75077:65;75156:21;-1:-1:-1;;;;;75181:16:0;;-1:-1:-1;;;;;;;;;;;75181:16:0;75180:56;;75235:1;75180:56;;;75201:31;75221:10;75201:19;:31::i;:::-;-1:-1:-1;;;;;75290:24:0;;;;;;:17;:24;;;;;;;;75315:10;75290:36;;;;;;;;75156:80;;-1:-1:-1;75290:53:0;;75331:11;75290:53;:40;:53;:::i;:::-;-1:-1:-1;;;;;75251:24:0;;;;;;:17;:24;;;;;;;;75276:10;75251:36;;;;;;;:92;;;;75388:27;;;:20;:27;;;;;:44;;75420:11;75388:44;:31;:44;:::i;:::-;-1:-1:-1;;;;;75358:27:0;;;;;;:20;:27;;;;;:74;;;;75449:70;;75480:10;75500:4;75507:11;75449:70;:30;:70;:::i;:::-;-1:-1:-1;;;;;75584:16:0;;-1:-1:-1;;;;;;;;;;;75584:16:0;75580:424;;;75669:40;;-1:-1:-1;;;75669:40:0;;75621:107;;-1:-1:-1;;;;;;;;;;;65082:42:0;75669:25;;:40;;75703:4;;75669:40;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;75669:40:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;75669:40:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;75669:40:0;;;;;;;;;75621:25;:107::i;:::-;75793:195;;;;;;;;-1:-1:-1;;;;;;;;;;;75865:25:0;75793:195;;75865:18;75793:195;;;;;;75772:10;-1:-1:-1;75749:34:0;;;:22;:34;;;;;-1:-1:-1;;;;;;;;;;;75749:41:0;;;;;;;;:239;;;;;;;;;;;75580:424;76100:10;-1:-1:-1;;;;;76023:151:0;76076:5;-1:-1:-1;;;;;76023:151:0;76047:10;-1:-1:-1;;;;;76023:151:0;;76148:11;76023:151;;;;;;;;;;;;;;;74836:1350;;74875:3;;74836:1350;;;;84012:1;;71518;;;;;;;74531:1662;;:::o;71753:463::-;71893:107;;-1:-1:-1;;;71893:107:0;;71845:7;;;;66754:42;;71893:61;;:107;;66862:3;;71994:4;;71893:107;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;71893:107:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;71893:107:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;71893:107:0;;;;;;;;;71870:130;;72020:188;-1:-1:-1;;;;;;;;;;;72073:5:0;72093:32;-1:-1:-1;;;;;;;;;;;72119:5:0;72093:16;:32::i;70411:36::-;;;;:::o;71535:146::-;71616:16;71657;71650:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;71650:23:0;;;;;;;;;;;;;;;;;;;;;;;71535:146;:::o;103309:214::-;59158:9;:7;:9::i;:::-;59150:54;;;;-1:-1:-1;;;59150:54:0;;;;;;;;;103439:76;;-1:-1:-1;;;103439:76:0;;103446:42;;103439:58;;:76;;103498:8;;103508:6;;103439:76;;;;66054:63;66109:8;66054:63;:::o;66874:47::-;66917:4;66874:47;:::o;70302:46::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;70302:46:0;;-1:-1:-1;70302:46:0;;-1:-1:-1;70302:46:0:o;65416:72::-;65446:42;65416:72;:::o;78874:320::-;71488:8;;78986:31;;-1:-1:-1;;;71488:8:0;;;;71487:9;71479:28;;;;-1:-1:-1;;;71479:28:0;;;;;;;;;83040:18;;83105:24;;78956:10;;83040:18;83010:27;;;;83267:114;78956:10;83040:18;83105:24;83267:7;:114::i;:::-;-1:-1:-1;;;;;83392:32:0;;;;;;:23;:32;;;;;;;;:54;;;83457:29;:38;;;;;:66;;;83588:11;:20;;;;;:41;;;83640:17;:26;;;;;:53;;;83142:239;;-1:-1:-1;83142:239:0;;-1:-1:-1;83142:239:0;-1:-1:-1;83142:239:0;-1:-1:-1;83759:187:0;83416:7;83142:239;;;;83759:12;:187::i;:::-;-1:-1:-1;;;;;83707:20:0;;;;;;:11;:20;;;;;;;;83729:17;:26;;;;;83706:240;;;;;;;;83957:15;:24;;;;83984:15;83957:42;;79061:12;:10;:12::i;:::-;79035:38;;79111:10;-1:-1:-1;;;;;79091:95:0;;79136:1;79152:23;79091:95;;;;;;;;82420:531;82534:16;;;82548:1;82534:16;;;;;;;;;82508:23;;82534:16;;;17:15:-1;;105:10;82534:16:0;88:34:-1;-1:-1;;82587:16:0;;;82601:1;82587:16;;;;;;;;;82508:42;;-1:-1:-1;82561:23:0;;82587:16;-1:-1:-1;82587:16:0;;;17:15:-1;;105:10;82587:16:0;88:34:-1;136:17;;-1:-1;82587:16:0;82561:42;;64999;82614:6;82621:1;82614:9;;;;;;;;;;;;;:17;-1:-1:-1;;;;;82614:17:0;;;-1:-1:-1;;;;;82614:17:0;;;;;-1:-1:-1;;;;;;;;;;;82642:6:0;82649:1;82642:9;;;;;;;;;;;;;:19;-1:-1:-1;;;;;82642:19:0;;;-1:-1:-1;;;;;82642:19:0;;;;;64918:42;82672:6;82679:1;82672:9;;;;;;;;;;;;;:17;-1:-1:-1;;;;;82672:17:0;;;-1:-1:-1;;;;;82672:17:0;;;;;-1:-1:-1;;;;;;;;;;;82700:6:0;82707:1;82700:9;;;;;;;;;;;;;:16;-1:-1:-1;;;;;82700:16:0;;;-1:-1:-1;;;;;82700:16:0;;;;;-1:-1:-1;;82727:6:0;82734:1;82727:9;;;;;;;;;;;;;:23;;;;;-1:-1:-1;;82761:6:0;82768:1;82761:9;;;;;;;;;;;;;:23;;;;;-1:-1:-1;;82795:6:0;82802:1;82795:9;;;;;;;;;;;;;:23;;;;;-1:-1:-1;;82829:6:0;82836:1;82829:9;;;;;;;;;;;;;:23;;;;;82873;82881:6;82889;82873:7;:23::i;:::-;82930:13;82937:5;82930:6;:13::i;:::-;;;;82420:531;;:::o;69315:33::-;;;;:::o;96617:564::-;96781:17;;64918:42;96694:14;96735:27;;;:20;:27;;;;96694:14;;96735:88;;96818:4;;96735:64;;:27;:64;:45;:64;:::i;:88::-;-1:-1:-1;;;;;;;;;;;96845:26:0;;:20;:26;;-1:-1:-1;;;;;;;;;;;96845:26:0;96726:97;;-1:-1:-1;96845:52:0;;96726:97;96845:52;:44;:52;:::i;:::-;96965:17;;64999:42;96919:27;;:20;:27;;;;96836:61;;-1:-1:-1;96919:114:0;;96836:61;;96919:88;;-1:-1:-1;;;97002:4:0;96919:64;;:27;:64;:45;:64;:::i;:114::-;97103:19;;-1:-1:-1;;;;;;;;;;;97055:29:0;;:20;:29;;;;96910:123;;-1:-1:-1;97055:118:0;;96910:123;;97055:92;;97142:4;;97055:68;;:29;:68;:47;:68;:::i;:118::-;97046:127;;96617:564;:::o;60052:109::-;59158:9;:7;:9::i;:::-;59150:54;;;;-1:-1:-1;;;59150:54:0;;;;;;;;;60125:28;60144:8;60125:18;:28::i;:::-;60052:109;:::o;64806:73::-;-1:-1:-1;;;;;;;;;;;64806:73:0;:::o;91491:507::-;71488:8;;-1:-1:-1;;;71488:8:0;;;;71487:9;71479:28;;;;-1:-1:-1;;;71479:28:0;;;;;;;;;91628:12;;;;:34;;-1:-1:-1;91644:18:0;;;91628:34;91624:367;;;91679:35;91691:7;91700:13;91679:11;:35::i;:::-;91733:12;;91729:114;;91766:61;;-1:-1:-1;;;91766:61:0;;-1:-1:-1;;;;;;;;;;;64837:42:0;91766:25;;:61;;91792:10;;91812:4;;91819:7;;91766:61;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;91766:61:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;91766:61:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;91766:61:0;;;;;;;;;;91729:114;91861:18;;91857:123;;91900:64;;-1:-1:-1;;;91900:64:0;;65284:42;;91900:22;;:64;;91923:10;;91943:4;;91950:13;;91900:64;;;;85657:3143;-1:-1:-1;;;;;86006:32:0;;85821:25;86006:32;;;:23;:32;;;;;;85821:25;;;;;;;;85988:51;;:13;;:51;:17;:51;:::i;:::-;-1:-1:-1;;;;;86109:38:0;;86050:32;86109:38;;;:29;:38;;;;;;85959:80;;-1:-1:-1;86050:32:0;86085:63;;:19;;:63;:23;:63;:::i;:::-;-1:-1:-1;;;;;86181:20:0;;;;;;:11;:20;;;;;;;;;86238:17;:26;;;;;;86296:11;:20;;;;;;86354:17;:26;;;;;;;;86181:20;;-1:-1:-1;86238:26:0;-1:-1:-1;86296:20:0;-1:-1:-1;86354:26:0;-1:-1:-1;86050:98:0;-1:-1:-1;86397:23:0;;;;:56;;-1:-1:-1;86424:29:0;;;86397:56;86393:2400;;;86470:13;86498:18;86531:16;86565:21;86588:22;86614:24;86630:7;86614:15;:24::i;:::-;86564:74;;-1:-1:-1;86564:74:0;-1:-1:-1;86663:55:0;86564:74;86699:18;86663:55;:35;:55;:::i;:::-;-1:-1:-1;;;86733:13:0;;;-1:-1:-1;86781:46:0;86733:13;86809:17;86781:27;:46::i;:::-;86761:66;-1:-1:-1;86852:61:0;:13;86888:24;86852:61;:35;:61;:::i;:::-;-1:-1:-1;;;86928:13:0;;;-1:-1:-1;86982:52:0;86928:13;87010:23;86982:27;:52::i;:::-;86956:78;-1:-1:-1;87055:19:0;;;;;:46;;-1:-1:-1;87078:23:0;;;87055:46;87051:800;;;87182:60;:14;87223:18;87182:60;:40;:60;:::i;:::-;-1:-1:-1;;;87261:13:0;;;-1:-1:-1;87314:51:0;:18;87261:13;87314:44;:51::i;:::-;-1:-1:-1;;;;;87465:24:0;;;;;;:15;:24;;;;;;87293:72;;-1:-1:-1;87465:24:0;;-1:-1:-1;87521:123:0;;-1:-1:-1;;;87566:4:0;87465:24;87521:22;:123::i;:::-;87508:136;-1:-1:-1;87671:43:0;:5;87508:136;87671:43;:31;:43;:::i;:::-;-1:-1:-1;;;87733:13:0;;;-1:-1:-1;87785:50:0;:17;87733:13;87785:43;:50::i;:::-;87765:70;;87051:800;87869:19;;;;;:52;;-1:-1:-1;87892:29:0;;;87869:52;87865:917;;;88002:66;:14;88043:24;88002:66;:40;:66;:::i;:::-;-1:-1:-1;;;88087:13:0;;;-1:-1:-1;88146:57:0;:24;88087:13;88146:50;:57::i;:::-;88119:84;-1:-1:-1;88296:13:0;88292:272;;-1:-1:-1;;;;;88345:24:0;;;;;;:15;:24;;;;;;;-1:-1:-1;88405:139:0;;-1:-1:-1;;;88454:4:0;88345:24;88405:22;:139::i;:::-;88392:152;;88292:272;88590:43;:5;88622:10;88590:43;:31;:43;:::i;:::-;-1:-1:-1;;;88652:13:0;;;-1:-1:-1;88710:56:0;:23;88652:13;88710:49;:56::i;:::-;88684:82;;87865:917;86393:2400;;;;;;85657:3143;;;;;;;;;:::o;88808:1520::-;-1:-1:-1;;;;;89125:24:0;;89065:7;89125:24;;;:15;:24;;;;;;89065:7;;89185:15;89166:34;;89162:1095;;89217:21;89253:18;89274:128;-1:-1:-1;;;89338:15:0;89372;89274:22;:128::i;:::-;89253:149;-1:-1:-1;89423:23:0;;89419:221;;89483:88;-1:-1:-1;;;89483:56:0;:18;89528:10;89483:56;:44;:56;:::i;:88::-;89590:34;;;;89467:104;-1:-1:-1;89419:221:0;89660:29;;89656:239;;89726:94;-1:-1:-1;;;89726:62:0;:24;89777:10;89726:62;:50;:62;:::i;:94::-;89839:40;;;;89710:110;-1:-1:-1;89656:239:0;-1:-1:-1;;;;;89934:33:0;;89911:20;89934:33;;;-1:-1:-1;;;;;;;;;;;89934:24:0;:33;:24;:33;;;89986:17;;89982:264;;90095:82;-1:-1:-1;;;90095:50:0;:12;90134:10;90095:50;:38;:50;:::i;:82::-;90196:34;;;;90079:98;-1:-1:-1;89982:264:0;89162:1095;;;;-1:-1:-1;90277:17:0;;90296:23;;-1:-1:-1;88808:1520:0;;-1:-1:-1;;;;88808:1520:0:o;2414:471::-;2472:7;2717:6;2713:47;;-1:-1:-1;2747:1:0;2740:8;;2713:47;2784:5;;;2788:1;2784;:5;:1;2808:5;;;;;:10;2800:56;;;;-1:-1:-1;;;2800:56:0;;;;;;;;3353:132;3411:7;3438:39;3442:1;3445;3438:39;;;;;;;;;;;;;;;;;:3;:39::i;1498:136::-;1556:7;1583:43;1587:1;1590;1583:43;;;;;;;;;;;;;;;;;:3;:43::i;72488:670::-;-1:-1:-1;;;;;72701:25:0;;72646:7;72701:25;;;:18;:25;;;;;;72646:7;;72701:51;;72731:20;72701:51;:29;:51;:::i;:::-;72671:81;-1:-1:-1;72767:24:0;72763:51;;72813:1;72806:8;;;;;72763:51;72831:15;72827:42;;72868:1;72861:8;;;;;72827:42;72882:53;;:::i;:::-;-1:-1:-1;;;;;;72938:29:0;;;;;;;:22;:29;;;;;;;;:36;;;;;;;;;;;;72882:92;;;;;;;;;;;;;;;;;;;;;;;;;72992:158;;73048:87;;73130:4;;73048:77;;73114:10;;73049:59;;:19;;:59;:23;:59;:::i;:::-;73048:65;:77;:65;:77;:::i;:87::-;72992:33;;;;;:158;:37;:158;:::i;:::-;72985:165;;;;72488:670;;;;;;;:::o;99285:372::-;99364:20;;:::i;:::-;99409:240;;;;;;;;99470:1;99452:15;:19;99409:240;;;;99499:18;:16;:18::i;:::-;99409:240;;99547:31;;-1:-1:-1;;;99547:31:0;;99409:240;;;;;-1:-1:-1;;;;;;;;;;;64837:42:0;99547:22;;:31;;-1:-1:-1;;;;;;;;;;;65082:42:0;99547:31;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;99547:31:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;99547:31:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;99547:31:0;;;;;;;;;99409:240;;;;-1:-1:-1;;;;;;;;;;;;;;;;99608:27:0;;:29;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;99608:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;99608:29:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;99608:29:0;;;;;;;;;99409:240;;99402:247;-1:-1:-1;99285:372:0;:::o;99665:1765::-;-1:-1:-1;;;;;99871:24:0;;99808:18;99871:24;;;:15;:24;;;;;;99910:21;;:26;;:74;;-1:-1:-1;99959:21:0;;-1:-1:-1;;99959:25:0;99940:44;;99910:74;99906:115;;;100008:1;100001:8;;;;;99906:115;-1:-1:-1;;;;;100057:33:0;;100033:21;100057:33;;;-1:-1:-1;;;;;;;;;;;100057:24:0;:33;:24;:33;;;100105:18;;100101:744;;100216:321;66668:12;100216:294;100297:194;66668:12;100419:1;100447:8;:21;;;100297:22;:194::i;:::-;100216:13;;66668:12;100252:239;100216:294;:35;:294;:::i;:321::-;100203:334;;100673:160;100822:10;100673:144;100714:13;100746:16;100781:8;:21;;;100673:22;:144::i;:160::-;100660:173;;100101:744;-1:-1:-1;;;;;100921:20:0;;;;;;:11;:20;;;;;;;;;-1:-1:-1;;;;;;;;;;;100870:32:0;;;;;;;:143;;101002:10;;100870:72;;:50;:72::i;:143::-;101091:20;;;;;-1:-1:-1;;;;;101039:33:0;;:24;:33;;;:24;:33;;;:24;:33;;;;100857:156;;-1:-1:-1;101039:127:0;;100857:156;;101039:97;;-1:-1:-1;;;101131:4:0;101039:73;;:33;:73;:51;:73;:::i;:127::-;101369:22;;;;-1:-1:-1;;;;;101314:35:0;;:26;:35;;;:26;;:35;:26;:35;;;;;101273:22;;;;101026:140;;-1:-1:-1;101273:149:0;;101026:140;;101273:119;;101369:22;;101273:77;;;:40;:77;:::i;:149::-;101260:162;99665:1765;-1:-1:-1;;;;;99665:1765:0:o;79497:575::-;79573:25;79600:31;79633:26;79697:19;79708:7;79697:10;:19::i;:::-;79677:39;;79753:12;:10;:12::i;:::-;79727:38;;79797:13;:11;:13::i;:::-;79776:34;;79848:10;-1:-1:-1;;;;;79828:111:0;;79873:17;79905:23;79828:111;;;;;;;;;;;;;;;;79955:23;;79952:113;;79999:54;;-1:-1:-1;;;;;;;;;;;65687:42:0;80015:10;;79999:54;;;;80034:18;;79999:54;;;;;;;;;;79952:113;79497:575;;;;;:::o;93011:435::-;93088:19;-1:-1:-1;;;;;93110:14:0;;-1:-1:-1;;;;;;;;;;;93110:14:0;:32;;93137:5;93110:32;;;-1:-1:-1;;;;;;;;;;;93110:32:0;-1:-1:-1;;;;;93177:33:0;;93155:19;93177:33;;;:20;:33;;;;;;93088:54;;-1:-1:-1;93229:16:0;93221:40;;;;-1:-1:-1;;;93221:40:0;;;;;;;;;93302:78;93346:33;93367:11;93346:16;:6;93357:4;93346:16;:10;:16;:::i;:33::-;-1:-1:-1;;;;;93302:25:0;;;;;;:18;:25;;;;;;;:78;:43;:78;:::i;:::-;-1:-1:-1;;;;;93274:25:0;;;;;;:18;:25;;;;;;;:106;;;;93398:40;;93412:10;;93398:40;;;;93431:6;;93398:40;;;;;;;;;;93011:435;;;;:::o;80080:737::-;80235:10;80160:25;80223:23;;;:11;:23;;;;;;80261:22;;80257:553;;80312:10;80326:1;80300:23;;;:11;:23;;;;;:27;80342:457;;;;80374:104;80409:10;80442:17;80374:12;:104::i;:::-;80342:457;;;80523:37;;-1:-1:-1;;;80523:37:0;;80563:17;;-1:-1:-1;;;;;;;;;;;64837:42:0;80523:22;;:37;;80554:4;;80523:37;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;80523:37:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;80523:37:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;80523:37:0;;;;;;;;;:57;80519:192;;;64918:42;-1:-1:-1;;;;;80663:26:0;;:28;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;80663:28:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;80663:28:0;;;;80519:192;80731:52;;-1:-1:-1;;;80731:52:0;;-1:-1:-1;;;;;;;;;;;64837:42:0;80731:21;;:52;;80753:10;;80765:17;;80731:52;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;80731:52:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;80731:52:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;80731:52:0;;;;;;;;;;80080:737;;;:::o;81178:786::-;81237:7;81278:10;81237:7;81323:32;-1:-1:-1;;;;;;;;;;;81278:10:0;81323:16;:32::i;:::-;81299:56;-1:-1:-1;81369:18:0;81366:57;;81410:1;81403:8;;;;;;81366:57;81475:40;;-1:-1:-1;;;81475:40:0;;81435:91;;-1:-1:-1;;;;;;;;;;;65082:42:0;81475:25;;:40;;81509:4;;81475:40;;;;81435:91;81539:20;81562:50;-1:-1:-1;;;;;;;;;;;81588:5:0;81595:13;81610:1;81562:18;:50::i;:::-;81664:151;;;;;;;;-1:-1:-1;;;;;;;;;;;81728:25:0;81664:151;;-1:-1:-1;81728:18:0;81664:151;;;;;;-1:-1:-1;;;;;81625:29:0;;;;:22;:29;;;;;-1:-1:-1;;;;;;;;;;;81625:36:0;;;;;;;;:190;;;;;;;;;;;81539:73;-1:-1:-1;81830:17:0;;81826:97;;81864:47;-1:-1:-1;;;;;;;;;;;81891:5:0;81898:12;81864:47;:26;:47;:::i;:::-;81944:12;-1:-1:-1;;;81178:786:0;:::o;1042:181::-;1100:7;1132:5;;;1156:6;;;;1148:46;;;;-1:-1:-1;;;1148:46:0;;;;;;;;15871:115;15934:7;15966:2;15961;:7;:17;;15976:2;15961:17;;;-1:-1:-1;15971:2:0;;15871:115;-1:-1:-1;15871:115:0:o;94460:218::-;94538:7;94570:100;64999:42;-1:-1:-1;;;;;94642:25:0;;:27;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;94642:27:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;94642:27:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;94642:27:0;;;;;;;;;94570:29;;-1:-1:-1;;;94570:29:0;;:53;;-1:-1:-1;;;94618:4:0;-1:-1:-1;;;;;;;;;;;64837:42:0;94570:22;;:29;;64999:42;;94570:29;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;94570:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;94570:29:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;94570:29:0;;;;;;;;57737:98;57817:10;57737:98;:::o;74040:481::-;74157:38;;-1:-1:-1;;;74157:38:0;;74128:26;;-1:-1:-1;;;;;;;;;;;65687:42:0;74157:23;;:38;;74189:4;;74157:38;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;74157:38:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;74157:38:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;74157:38:0;;;;;;;;;74206:119;;-1:-1:-1;;;74206:119:0;;74128:67;;-1:-1:-1;66754:42:0;;74206:43;;:119;;66862:3;;74308:6;;74206:119;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;74206:119:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;74359:38:0;;-1:-1:-1;;;74359:38:0;;74336:20;;-1:-1:-1;74400:18:0;;-1:-1:-1;;;;;;;;;;;;65687:42:0;74359:23;;:38;;74391:4;;74359:38;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;74359:38:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;74359:38:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;74359:38:0;;;;;;;;;:59;;-1:-1:-1;74433:17:0;;74429:85;;74467:35;-1:-1:-1;;;;;;;;;;;74489:12:0;74467:14;:35::i;11991:176::-;12100:58;;12074:85;;12093:5;;-1:-1:-1;;;12123:23:0;12100:58;;12148:2;;12152:5;;12100:58;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;12100:58:0;;;49:4:-1;25:18;;61:17;;-1:-1;;;;;182:15;-1:-1;;;;;;12100:58:0;;;179:29:-1;;;;160:49;;;12074:18:0;:85::i;12175:204::-;12302:68;;12276:95;;12295:5;;-1:-1:-1;;;12325:27:0;12302:68;;12354:4;;12360:2;;12364:5;;12302:68;;;;12276:95;12175:204;;;;:::o;73555:477::-;73669:38;;-1:-1:-1;;;73669:38:0;;73640:26;;-1:-1:-1;;;;;;;;;;;65687:42:0;73669:23;;:38;;73701:4;;73669:38;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;73669:38:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;73669:38:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;73669:38:0;;;;;;;;;73718:118;;-1:-1:-1;;;73718:118:0;;73640:67;;-1:-1:-1;66754:42:0;;73718;;:118;;66862:3;;73819:6;;73718:118;;;;80825:345;80977:10;80884:31;80959:29;;;:17;:29;;;;;;81003:28;;80999:164;;81066:10;81080:1;81048:29;;;:17;:29;;;;;;:33;;;;81096:55;-1:-1:-1;;;81096:55:0;;65284:42;;81096:18;;:55;;81066:10;81127:23;;81096:55;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;81096:55:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;81096:55:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;81096:55:0;;;;;;;;;;80825:345;:::o;60267:229::-;-1:-1:-1;;;;;60341:22:0;;60333:73;;;;-1:-1:-1;;;60333:73:0;;;;;;;;;60443:6;;;60422:38;;-1:-1:-1;;;;;60422:38:0;;;;60443:6;;;60422:38;;;60471:6;:17;;-1:-1:-1;;;;;;60471:17:0;-1:-1:-1;;;;;60471:17:0;;;;;;;;;;60267:229::o;92006:761::-;92182:20;:18;:20::i;:::-;92159:19;92120:82;92140:17;92120:82;92121:17;92120:82;92121:17;92237:19;:17;:19::i;:::-;92215:41;-1:-1:-1;92275:16:0;92267:43;;;;-1:-1:-1;;;92267:43:0;;;;;;;;;92425:18;;92344:100;;:62;92394:11;92344:31;:7;-1:-1:-1;;;92344:31:0;:25;:31;:::i;:100::-;92323:18;:121;92571:24;;92484:112;;:68;92540:11;92484:37;:13;-1:-1:-1;;;92484:37:0;:31;:37;:::i;:112::-;92457:24;:139;92630:15;92609:18;:36;92663:96;;92688:10;;92663:96;;;;92713:7;;92735:13;;92663:96;;;;;;;;;;92006:761;;;:::o;4015:345::-;4101:7;4203:12;4196:5;4188:28;;;;-1:-1:-1;;;4188:28:0;;;;;;;;;;;4227:9;4243:1;4239;:5;;;;1971:192;2057:7;2093:12;2085:6;;;;2077:29;;;;-1:-1:-1;;;2077:29:0;;;;;;;;;;-1:-1:-1;;;2129:5:0;;;1971:192::o;81972:440::-;-1:-1:-1;;;;;82115:32:0;;:23;:32;;;-1:-1:-1;;;;;;;;;;;82115:23:0;:32;:23;:32;;;:58;;82166:6;82115:58;:50;:58;:::i;:::-;-1:-1:-1;;;;;82080:32:0;;:23;:32;;;-1:-1:-1;;;;;;;;;;;82080:23:0;:32;;;:23;:32;;:93;;;;-1:-1:-1;;;;;;;;;;;82215:26:0;;:20;:26;;-1:-1:-1;;;;;;;;;;;82215:26:0;:52;;82260:6;82215:52;:44;:52;:::i;:::-;-1:-1:-1;;;;;;;;;;;82186:26:0;;;;:20;:26;;-1:-1:-1;;;;;;;;;;;82186:81:0;;;;:26;82285:119;-1:-1:-1;;;;;82285:119:0;;;64837:42;82285:119;;;;;;82387:6;;82285:119;;;;;;;;;;81972:440;;:::o;14030:1114::-;14634:27;14642:5;-1:-1:-1;;;;;14634:25:0;;:27::i;:::-;14626:71;;;;-1:-1:-1;;;14626:71:0;;;;;;;;;14771:12;14785:23;14820:5;-1:-1:-1;;;;;14812:19:0;14832:4;14812:25;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;14770:67:0;;;;14856:7;14848:52;;;;-1:-1:-1;;;14848:52:0;;;;;;;;;14917:17;;:21;14913:224;;15059:10;15048:30;;;;;;;;;;;;;;15040:85;;;;-1:-1:-1;;;15040:85:0;;;;;;;;9115:619;9175:4;9643:20;;9486:66;9683:23;;;;;;:42;;-1:-1:-1;;9710:15:0;;;9675:51;-1:-1:-1;;9115:619:0:o;71243:32283::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;71243:32283:0;-1:-1:-1;;;;;71243:32283:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;71243:32283:0;;;-1:-1:-1;71243:32283:0;:::i;:::-;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;-1:-1:-1;;;;;;71243:32283:0;;;;;;;5:130:-1;72:20;;97:33;72:20;97:33;;160:352;;;290:3;283:4;275:6;271:17;267:27;257:2;;308:1;305;298:12;257:2;-1:-1;328:20;;368:18;357:30;;354:2;;;400:1;397;390:12;354:2;434:4;426:6;422:17;410:29;;485:3;477:4;469:6;465:17;455:8;451:32;448:41;445:2;;;502:1;499;492:12;445:2;250:262;;;;;;538:707;;655:3;648:4;640:6;636:17;632:27;622:2;;673:1;670;663:12;622:2;710:6;697:20;732:80;747:64;804:6;747:64;;;732:80;;;723:89;;829:5;854:6;847:5;840:21;884:4;876:6;872:17;862:27;;906:4;901:3;897:14;890:21;;959:6;1006:3;998:4;990:6;986:17;981:3;977:27;974:36;971:2;;;1023:1;1020;1013:12;971:2;1048:1;1033:206;1058:6;1055:1;1052:13;1033:206;;;1116:3;1138:37;1171:3;1159:10;1138:37;;;1126:50;;-1:-1;1199:4;1190:14;;;;1218;;;;;1080:1;1073:9;1033:206;;;1037:14;615:630;;;;;;;;1649:707;;1766:3;1759:4;1751:6;1747:17;1743:27;1733:2;;1784:1;1781;1774:12;1733:2;1821:6;1808:20;1843:80;1858:64;1915:6;1858:64;;1843:80;1834:89;;1940:5;1965:6;1958:5;1951:21;1995:4;1987:6;1983:17;1973:27;;2017:4;2012:3;2008:14;2001:21;;2070:6;2117:3;2109:4;2101:6;2097:17;2092:3;2088:27;2085:36;2082:2;;;2134:1;2131;2124:12;2082:2;2159:1;2144:206;2169:6;2166:1;2163:13;2144:206;;;2227:3;2249:37;2282:3;2270:10;2249:37;;;2237:50;;-1:-1;2310:4;2301:14;;;;2329;;;;;2191:1;2184:9;2144:206;;2364:124;2428:20;;2453:30;2428:20;2453:30;;2495:128;2570:13;;2588:30;2570:13;2588:30;;2669:509;;2795:4;2783:9;2778:3;2774:19;2770:30;2767:2;;;2813:1;2810;2803:12;2767:2;2831:20;2846:4;2831:20;;;2822:29;-1:-1;2903:1;2935:60;2991:3;2971:9;2935:60;;;2910:86;;-1:-1;3063:2;3096:60;3152:3;3128:22;;;3096:60;;;3089:4;3082:5;3078:16;3071:86;3017:151;2761:417;;;;;3185:130;3252:20;;3277:33;3252:20;3277:33;;3322:134;3400:13;;3418:33;3400:13;3418:33;;3463:241;;3567:2;3555:9;3546:7;3542:23;3538:32;3535:2;;;3583:1;3580;3573:12;3535:2;3618:1;3635:53;3680:7;3660:9;3635:53;;3711:366;;;3832:2;3820:9;3811:7;3807:23;3803:32;3800:2;;;3848:1;3845;3838:12;3800:2;3883:1;3900:53;3945:7;3925:9;3900:53;;;3890:63;;3862:97;3990:2;4008:53;4053:7;4044:6;4033:9;4029:22;4008:53;;;3998:63;;3969:98;3794:283;;;;;;4084:366;;;4205:2;4193:9;4184:7;4180:23;4176:32;4173:2;;;4221:1;4218;4211:12;4173:2;4256:1;4273:53;4318:7;4298:9;4273:53;;;4263:63;;4235:97;4363:2;4381:53;4426:7;4417:6;4406:9;4402:22;4381:53;;4457:397;;;4596:2;4584:9;4575:7;4571:23;4567:32;4564:2;;;4612:1;4609;4602:12;4564:2;4647:31;;4698:18;4687:30;;4684:2;;;4730:1;4727;4720:12;4684:2;4758:80;4830:7;4821:6;4810:9;4806:22;4758:80;;;4748:90;;;;4626:218;4558:296;;;;;;4861:959;;;;;;;5104:2;5092:9;5083:7;5079:23;5075:32;5072:2;;;5120:1;5117;5110:12;5072:2;5155:31;;5206:18;5195:30;;5192:2;;;5238:1;5235;5228:12;5192:2;5266:80;5338:7;5329:6;5318:9;5314:22;5266:80;;;5256:90;;;;5134:218;5411:2;5400:9;5396:18;5383:32;5435:18;5427:6;5424:30;5421:2;;;5467:1;5464;5457:12;5421:2;5495:80;5567:7;5558:6;5547:9;5543:22;5495:80;;;5485:90;;;;5362:219;5640:2;5629:9;5625:18;5612:32;5664:18;5656:6;5653:30;5650:2;;;5696:1;5693;5686:12;5650:2;5724:80;5796:7;5787:6;5776:9;5772:22;5724:80;;;5714:90;;;;5591:219;5066:754;;;;;;;;;5827:638;;;5998:2;5986:9;5977:7;5973:23;5969:32;5966:2;;;6014:1;6011;6004:12;5966:2;6049:31;;6100:18;6089:30;;6086:2;;;6132:1;6129;6122:12;6086:2;6152:78;6222:7;6213:6;6202:9;6198:22;6152:78;;;6142:88;;6028:208;6295:2;6284:9;6280:18;6267:32;6319:18;6311:6;6308:30;6305:2;;;6351:1;6348;6341:12;6305:2;6371:78;6441:7;6432:6;6421:9;6417:22;6371:78;;6472:235;;6573:2;6561:9;6552:7;6548:23;6544:32;6541:2;;;6589:1;6586;6579:12;6541:2;6624:1;6641:50;6683:7;6663:9;6641:50;;6714:257;;6826:2;6814:9;6805:7;6801:23;6797:32;6794:2;;;6842:1;6839;6832:12;6794:2;6877:1;6894:61;6947:7;6927:9;6894:61;;6978:315;;7119:2;7107:9;7098:7;7094:23;7090:32;7087:2;;;7135:1;7132;7125:12;7087:2;7170:1;7187:90;7269:7;7249:9;7187:90;;7300:241;;7404:2;7392:9;7383:7;7379:23;7375:32;7372:2;;;7420:1;7417;7410:12;7372:2;7455:1;7472:53;7517:7;7497:9;7472:53;;7548:263;;7663:2;7651:9;7642:7;7638:23;7634:32;7631:2;;;7679:1;7676;7669:12;7631:2;7714:1;7731:64;7787:7;7767:9;7731:64;;7818:366;;;7939:2;7927:9;7918:7;7914:23;7910:32;7907:2;;;7955:1;7952;7945:12;7907:2;7990:1;8007:53;8052:7;8032:9;8007:53;;8191:491;;;;8329:2;8317:9;8308:7;8304:23;8300:32;8297:2;;;8345:1;8342;8335:12;8297:2;8380:1;8397:53;8442:7;8422:9;8397:53;;;8387:63;;8359:97;8487:2;8505:53;8550:7;8541:6;8530:9;8526:22;8505:53;;;8495:63;;8466:98;8595:2;8613:53;8658:7;8649:6;8638:9;8634:22;8613:53;;;8603:63;;8574:98;8291:391;;;;;;8690:173;;8777:46;8819:3;8811:6;8777:46;;;-1:-1;;8852:4;8843:14;;8770:93;8871:142;8962:45;9001:5;8962:45;;;8957:3;8950:58;8944:69;;;9020:103;9093:24;9111:5;9093:24;;9281:690;;9426:54;9474:5;9426:54;;;9493:86;9572:6;9567:3;9493:86;;;9486:93;;9600:56;9650:5;9600:56;;;9676:7;9704:1;9689:260;9714:6;9711:1;9708:13;9689:260;;;9781:6;9775:13;9802:63;9861:3;9846:13;9802:63;;;9795:70;;9882:60;9935:6;9882:60;;;9872:70;-1:-1;;9736:1;9729:9;9689:260;;;-1:-1;9962:3;;9405:566;-1:-1;;;;;9405:566;9979:104;10056:21;10071:5;10056:21;;10090:356;;10218:38;10250:5;10218:38;;;10268:88;10349:6;10344:3;10268:88;;;10261:95;;10361:52;10406:6;10401:3;10394:4;10387:5;10383:16;10361:52;;;10425:16;;;;;10198:248;-1:-1;;10198:248;10453:152;10549:50;10593:5;10549:50;;11129:142;11220:45;11259:5;11220:45;;11278:347;;11390:39;11423:5;11390:39;;;11441:71;11505:6;11500:3;11441:71;;;11434:78;;11517:52;11562:6;11557:3;11550:4;11543:5;11539:16;11517:52;;;11590:29;11612:6;11590:29;;;11581:39;;;;11370:255;-1:-1;;;11370:255;11633:375;;11793:67;11857:2;11852:3;11793:67;;;11893:34;11873:55;;-1:-1;;;11957:2;11948:12;;11941:30;11999:2;11990:12;;11779:229;-1:-1;;11779:229;12017:327;;12177:67;12241:2;12236:3;12177:67;;;12277:29;12257:50;;12335:2;12326:12;;12163:181;-1:-1;;12163:181;12353:311;;12513:67;12577:2;12572:3;12513:67;;;-1:-1;;;12593:34;;12655:2;12646:12;;12499:165;-1:-1;;12499:165;12673:332;;12833:67;12897:2;12892:3;12833:67;;;12933:34;12913:55;;12996:2;12987:12;;12819:186;-1:-1;;12819:186;13014:314;;13174:67;13238:2;13233:3;13174:67;;;-1:-1;;;13254:37;;13319:2;13310:12;;13160:168;-1:-1;;13160:168;13337:315;;13497:67;13561:2;13556:3;13497:67;;;-1:-1;;;13577:38;;13643:2;13634:12;;13483:169;-1:-1;;13483:169;13661:314;;13821:67;13885:2;13880:3;13821:67;;;-1:-1;;;13901:37;;13966:2;13957:12;;13807:168;-1:-1;;13807:168;13984:370;;14144:67;14208:2;14203:3;14144:67;;;14244:34;14224:55;;-1:-1;;;14308:2;14299:12;;14292:25;14345:2;14336:12;;14130:224;-1:-1;;14130:224;14363:313;;14523:67;14587:2;14582:3;14523:67;;;-1:-1;;;14603:36;;14667:2;14658:12;;14509:167;-1:-1;;14509:167;14685:312;;14845:67;14909:2;14904:3;14845:67;;;-1:-1;;;14925:35;;14988:2;14979:12;;14831:166;-1:-1;;14831:166;15006:332;;15166:67;15230:2;15225:3;15166:67;;;15266:34;15246:55;;15329:2;15320:12;;15152:186;-1:-1;;15152:186;15347:313;;15507:67;15571:2;15566:3;15507:67;;;-1:-1;;;15587:36;;15651:2;15642:12;;15493:167;-1:-1;;15493:167;15669:379;;15829:67;15893:2;15888:3;15829:67;;;15929:34;15909:55;;-1:-1;;;15993:2;15984:12;;15977:34;16039:2;16030:12;;15815:233;-1:-1;;15815:233;16057:305;;16217:66;16281:1;16276:3;16217:66;;;-1:-1;;;16296:29;;16353:2;16344:12;;16203:159;-1:-1;;16203:159;16371:331;;16531:67;16595:2;16590:3;16531:67;;;16631:33;16611:54;;16693:2;16684:12;;16517:185;-1:-1;;16517:185;16711:314;;16871:67;16935:2;16930:3;16871:67;;;-1:-1;;;16951:37;;17016:2;17007:12;;16857:168;-1:-1;;16857:168;17033:113;17116:24;17134:5;17116:24;;17153:262;;17297:93;17386:3;17377:6;17297:93;;17422:213;17540:2;17525:18;;17554:71;17529:9;17598:6;17554:71;;17642:451;17824:2;17809:18;;17838:79;17813:9;17890:6;17838:79;;;17928:72;17996:2;17985:9;17981:18;17972:6;17928:72;;;18011;18079:2;18068:9;18064:18;18055:6;18011:72;;18100:340;18254:2;18239:18;;18268:79;18243:9;18320:6;18268:79;;;18358:72;18426:2;18415:9;18411:18;18402:6;18358:72;;18447:435;18621:2;18606:18;;18635:71;18610:9;18679:6;18635:71;;18889:324;19035:2;19020:18;;19049:71;19024:9;19093:6;19049:71;;19220:361;19388:2;19402:47;;;19373:18;;19463:108;19373:18;19557:6;19463:108;;19588:201;19700:2;19685:18;;19714:65;19689:9;19752:6;19714:65;;19796:239;19927:2;19912:18;;19941:84;19916:9;19998:6;19941:84;;20820:340;20974:2;20959:18;;20988:79;20963:9;21040:6;20988:79;;21167:301;21305:2;21319:47;;;21290:18;;21380:78;21290:18;21444:6;21380:78;;21475:407;21666:2;21680:47;;;21651:18;;21741:131;21651:18;21741:131;;21889:407;22080:2;22094:47;;;22065:18;;22155:131;22065:18;22155:131;;22303:407;22494:2;22508:47;;;22479:18;;22569:131;22479:18;22569:131;;22717:407;22908:2;22922:47;;;22893:18;;22983:131;22893:18;22983:131;;23131:407;23322:2;23336:47;;;23307:18;;23397:131;23307:18;23397:131;;23545:407;23736:2;23750:47;;;23721:18;;23811:131;23721:18;23811:131;;23959:407;24150:2;24164:47;;;24135:18;;24225:131;24135:18;24225:131;;24373:407;24564:2;24578:47;;;24549:18;;24639:131;24549:18;24639:131;;24787:407;24978:2;24992:47;;;24963:18;;25053:131;24963:18;25053:131;;25201:407;25392:2;25406:47;;;25377:18;;25467:131;25377:18;25467:131;;25615:407;25806:2;25820:47;;;25791:18;;25881:131;25791:18;25881:131;;26029:407;26220:2;26234:47;;;26205:18;;26295:131;26205:18;26295:131;;26443:407;26634:2;26648:47;;;26619:18;;26709:131;26619:18;26709:131;;26857:407;27048:2;27062:47;;;27033:18;;27123:131;27033:18;27123:131;;27271:407;27462:2;27476:47;;;27447:18;;27537:131;27447:18;27537:131;;27685:407;27876:2;27890:47;;;27861:18;;27951:131;27861:18;27951:131;;28099:213;28217:2;28202:18;;28231:71;28206:9;28275:6;28231:71;;28319:324;28465:2;28450:18;;28479:71;28454:9;28523:6;28479:71;;;28561:72;28629:2;28618:9;28614:18;28605:6;28561:72;;28650:340;28804:2;28789:18;;28818:71;28793:9;28862:6;28818:71;;;28900:80;28976:2;28965:9;28961:18;28952:6;28900:80;;28997:324;29143:2;29128:18;;29157:71;29132:9;29201:6;29157:71;;29328:435;29502:2;29487:18;;29516:71;29491:9;29560:6;29516:71;;;29598:72;29666:2;29655:9;29651:18;29642:6;29598:72;;29770:659;30000:3;29985:19;;30015:71;29989:9;30059:6;30015:71;;;30097:72;30165:2;30154:9;30150:18;30141:6;30097:72;;;30180;30248:2;30237:9;30233:18;30224:6;30180:72;;;30263;30331:2;30320:9;30316:18;30307:6;30263:72;;;30346:73;30414:3;30403:9;30399:19;30390:6;30346:73;;;29971:458;;;;;;;;;30436:256;30498:2;30492:9;30524:17;;;30599:18;30584:34;;30620:22;;;30581:62;30578:2;;;30656:1;30653;30646:12;30578:2;30672;30665:22;30476:216;;-1:-1;30476:216;30699:304;;30858:18;30850:6;30847:30;30844:2;;;30890:1;30887;30880:12;30844:2;-1:-1;30925:4;30913:17;;;30978:15;;30781:222;31321:151;31445:4;31436:14;;31393:79;31479:137;31582:12;;31553:63;31996:178;32114:19;;;32163:4;32154:14;;32107:67;32507:91;;32569:24;32587:5;32569:24;;32605:85;32671:13;32664:21;;32647:43;32697:121;-1:-1;;;;;32759:54;;32742:76;32904:129;;32991:37;33022:5;33040:147;;33132:50;33176:5;33132:50;;34228:116;;34315:24;34333:5;34315:24;;34595:268;34660:1;34667:101;34681:6;34678:1;34675:13;34667:101;;;34748:11;;;34742:18;34729:11;;;34722:39;34703:2;34696:10;34667:101;;;34783:6;34780:1;34777:13;34774:2;;;-1:-1;;34848:1;34830:16;;34823:27;34644:219;34871:97;34959:2;34939:14;-1:-1;;34935:28;;34919:49;34976:117;35045:24;35063:5;35045:24;;;35038:5;35035:35;35025:2;;35084:1;35081;35074:12;35100:111;35166:21;35181:5;35166:21;;35218:117;35287:24;35305:5;35287:24;
Swarm Source
bzzr://e5ca5ac211cc4197c473a7ab9fbd28c69d8a7ad2c02b9b3ffd337b9183bd40ad
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.