Source Code
Latest 25 from a total of 248 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Un Stake Mst | 1170064 | 246 days ago | IN | 0 ETH | 0.00000038 | ||||
| Un Stake Mst | 1170064 | 246 days ago | IN | 0 ETH | 0.00000153 | ||||
| Increwards Per W... | 1112322 | 271 days ago | IN | 0 ETH | 0.00000359 | ||||
| Increwards Per W... | 1109639 | 272 days ago | IN | 0 ETH | 0.00000347 | ||||
| Increwards Per W... | 1107208 | 273 days ago | IN | 0 ETH | 0.00000346 | ||||
| Increwards Per W... | 1104944 | 274 days ago | IN | 0 ETH | 0.00000353 | ||||
| Increwards Per W... | 1102906 | 275 days ago | IN | 0 ETH | 0.00000455 | ||||
| Increwards Per W... | 1101026 | 276 days ago | IN | 0 ETH | 0.00000324 | ||||
| Increwards Per W... | 1098098 | 277 days ago | IN | 0 ETH | 0.00000353 | ||||
| Increwards Per W... | 1095096 | 278 days ago | IN | 0 ETH | 0.00000353 | ||||
| Increwards Per W... | 1091518 | 279 days ago | IN | 0 ETH | 0.00000359 | ||||
| Increwards Per W... | 1088040 | 280 days ago | IN | 0 ETH | 0.00000347 | ||||
| Increwards Per W... | 1085974 | 281 days ago | IN | 0 ETH | 0.00000347 | ||||
| Increwards Per W... | 1083372 | 282 days ago | IN | 0 ETH | 0.00000353 | ||||
| Increwards Per W... | 1079993 | 283 days ago | IN | 0 ETH | 0.00000455 | ||||
| Increwards Per W... | 1076552 | 284 days ago | IN | 0 ETH | 0.00000324 | ||||
| Increwards Per W... | 1073286 | 285 days ago | IN | 0 ETH | 0.00000353 | ||||
| Increwards Per W... | 1069644 | 286 days ago | IN | 0 ETH | 0.00000588 | ||||
| Increwards Per W... | 1065917 | 287 days ago | IN | 0 ETH | 0.00000359 | ||||
| Increwards Per W... | 1062370 | 288 days ago | IN | 0 ETH | 0.00000353 | ||||
| Increwards Per W... | 1059198 | 289 days ago | IN | 0 ETH | 0.00000359 | ||||
| Increwards Per W... | 1055979 | 290 days ago | IN | 0 ETH | 0.0000047 | ||||
| Increwards Per W... | 1052529 | 291 days ago | IN | 0 ETH | 0.00000455 | ||||
| Increwards Per W... | 1050140 | 292 days ago | IN | 0 ETH | 0.00000395 | ||||
| Increwards Per W... | 1046384 | 293 days ago | IN | 0 ETH | 0.00000588 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
Contract Name:
MeridianMultiPoolStaking
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity)
/**
*Submitted for verification at taikoscan.io on 2024-08-22
*/
// File: contracts/utils/CheckContract.sol
pragma experimental ABIEncoderV2;
pragma solidity 0.6.12;
contract CheckContract {
/**
* Check that the account is an already deployed non-destroyed contract.
* See: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol#L12
*/
function checkContract(address _account) internal view {
require(_account != address(0), "Account cannot be zero address");
uint256 size;
// solhint-disable-next-line no-inline-assembly
assembly { size := extcodesize(_account) }
require(size > 0, "Account code size cannot be zero");
}
}
// File: contracts/utils/ReentrancyGuard.sol
pragma solidity 0.6.12;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor () internal {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and make it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
// On the first call to nonReentrant, _notEntered will be true
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}
// File: contracts/utils/SafeMath.sol
pragma solidity 0.6.12;
/**
* @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.
*/
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.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
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.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}
// File: contracts/utils/IERC20.sol
pragma solidity 0.6.12;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}
// File: contracts/utils/Address.sol
pragma solidity ^0.6.2;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
// solhint-disable-next-line no-inline-assembly
assembly { size := extcodesize(account) }
return size > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
// solhint-disable-next-line avoid-low-level-calls, avoid-call-value
(bool success, ) = recipient.call{ value: amount }("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain`call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.call{ value: value }(data);
return _verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.3._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.3._
*/
function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.delegatecall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
// solhint-disable-next-line no-inline-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
// File: contracts/utils/SafeERC20.sol
pragma solidity 0.6.12;
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using SafeMath for uint256;
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(IERC20 token, address spender, uint256 value) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
// solhint-disable-next-line max-line-length
require((value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).add(value);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) { // Return data is optional
// solhint-disable-next-line max-line-length
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
// File: contracts/InvestmentPools.sol
pragma solidity ^0.6.12;
// Users can invest in a set of predefined investment pools
// Each pool has a min redemption period and staking multiplier. The longer the duration the greater the multiplier
// The base pool has a multiplier of 1 and allows for immediate withdrawls.
// The pool multiplier is applied to the amount invested to give the users weighted stake in that pool
// Vesting starts immediately the deposit is made
// A user can only redeem an investment from a pool once the vesting period ends
// A user can redeem all or part of a fully vested investment in a pool
// A max limit is placed on the number of live investments in any pool in order to avoid gas or security issues
contract InvestmentPools {
using SafeMath for uint256;
// Note that if the number of Pools in InvestmentType is changed then the isValidInvestmentType function MUST be updated
enum InvestmentType {Pool1, Pool2, Pool3, Pool4, Pool5, Pool6, Pool7, Pool8, Pool9, Pool10}
uint constant public MAX_NUM_OF_POOLS = 10; // NOTE This MUST be equal to the number of Pools in InvestmentType
uint constant public ONE_HUNDRED_PCNT = 1000;
uint constant public MIN_MULTIPLIER = 1000; // = multiplier of 1
uint constant public MAX_MULTIPLIER = 3000; // = multiplier of 3
uint constant public MAX_INVESTMENTS_PER_POOL = 10; // restricts the number of investments for each pool to prevent gas issues
uint constant public ONE_DAY_IN_SECONDS = 86400;
bool public investmentsInitialized;
address public gov;
uint public numberOfPools;
// user stakes weighted based on lock up period
mapping (address => uint) public weightedStake;
mapping(InvestmentType => uint256) public presetMultipliers;
mapping(InvestmentType => uint256) public presetDurations;
struct Investment {
uint256 amount;
uint256 multiplier;
uint256 vestingTimestamp;
}
struct UserInvestmentPool {
uint256 total;
Investment[] investments;
}
// mapping of user investments user => investment type => User Investment Pool
mapping(address => mapping(InvestmentType => UserInvestmentPool)) public userInvestments;
constructor() public {
gov = msg.sender;
}
event GovChanged(address _gov);
modifier onlyGov() {
require(msg.sender == gov, "MeridianStaking: Forbidden");
_;
}
function setGov(address _newGov) external onlyGov {
require(_newGov != address(0),"MeridianStaking: Invalid address");
gov = _newGov;
emit GovChanged(_newGov);
}
function renounceGov(bool _renounce) external onlyGov {
require(_renounce == true,"MeridianStaking: renounce must be true");
gov = address(0);
emit GovChanged(gov);
}
// Note duration set in days where 1 = 1 day
// Note multipliers must be >= 1000 where 1000 = multiply by 1. eg a multiplier of 1100 will add 10% to the actual investent amount
function initializeInvestments(uint256[] memory multipliers, uint256[] memory durations) external onlyGov {
require(!investmentsInitialized, "Already Initialized");
require(multipliers.length < MAX_NUM_OF_POOLS,"Too many pools");
require(multipliers.length == durations.length, "Invalid input arrays");
investmentsInitialized = true;
presetMultipliers[InvestmentType.Pool1] = MIN_MULTIPLIER; // base pool multiplier = 1
presetDurations[InvestmentType.Pool1] = 0; // base pool duration zero i.e., immediate withdrawals
for (uint256 i = 0; i < multipliers.length; i++) {
require(multipliers[i] >= MIN_MULTIPLIER && multipliers[i] <= MAX_MULTIPLIER, "Invalid investment multiplier");
require(durations[i] >= 0, "Invalid investment duration");
InvestmentType poolType = InvestmentType(uint256(InvestmentType.Pool1) + i + 1);
presetMultipliers[poolType] = multipliers[i];
presetDurations[poolType] = durations[i];
}
numberOfPools = multipliers.length+1;
}
function adjustInvestment(uint256 _multiplier, uint256 _duration, InvestmentType _pool) external onlyGov {
require(investmentsInitialized, "Use initializeInvestments to first setup pools");
require(isValidInvestmentType(_pool), "Invalid InvestmentType");
require(uint(_pool) <= numberOfPools,"Not next pool. Pools must be set up sequentially");
require(_multiplier >= MIN_MULTIPLIER && _multiplier <= MAX_MULTIPLIER, "Invalid investment multiplier");
// The duration of a pool cannot be reduced once set it can only be increased
require(_duration >= 0 && _duration >= presetDurations[_pool], "Invalid investment duration");
presetMultipliers[_pool] = _multiplier;
presetDurations[_pool] = _duration;
if (uint(_pool) == numberOfPools) {numberOfPools = numberOfPools + 1;}
}
// Function takes in an _amount of tokens to stake and an investment type (min lockup period and multiplier)
// calculates the investment uplift due to the agreed lockup period and adds uplifted amount to the users wighted investment
// sets up a new deposit with appropriate vesting end time and
// returns the total weighted staking value for this user for all investments
function StakeRequest(address _user, uint256 _amount, InvestmentType _type) internal returns (uint256) {
require(investmentsInitialized, "Contract not yet initialized");
require(_amount > 0,"Invalid stake");
require(isValidInvestmentType(_type), "Invalid InvestmentType");
require(userInvestments[_user][_type].investments.length < MAX_INVESTMENTS_PER_POOL, "Max number of investments exceeded for this pool");
// add the new stake to the appropriate investment pool for this user
userInvestments[_user][_type].total = userInvestments[_user][_type].total.add(_amount);
uint256 vestingEndTime = block.timestamp.add(ONE_DAY_IN_SECONDS.mul(presetDurations[_type]));
userInvestments[_user][_type].investments.push(Investment({
amount: _amount,
multiplier: presetMultipliers[_type],
vestingTimestamp: vestingEndTime
}));
// update the weighted investment stake
weightedStake[_user]= weightedStake[_user].add(_amount.mul(presetMultipliers[_type]).div(ONE_HUNDRED_PCNT));
return weightedStake[_user];
}
// Note Investments are managed using a priority queue system where investments that vest later are further down the queue.
// This allows searching from the start of the array for the investments that are ready to be redeemed
// If the value of investments avaiable to redeem is greater than _amount then the investment array is adjusted appropriatly
// and the new overall weighted investment for this user is returned.
// If the value of investments ready to redeem is less than _amount then the function returns without any changes
// and returns the original weighted average for the investments
// Note The calling function must check to see if the weighted average has changed to confirm that the redemption is valid
function redemptionRequest(address _user, uint256 _amount) internal returns (uint256) {
require(investmentsInitialized, "Contract not yet initialized");
require(_amount > 0,"Invalid amount");
uint256 availableToRedeem;
uint256 priorAmount;
uint256 adjustedWeightedStake;
uint256 partRedemption;
uint256[] memory poolRedemptionIndex = new uint256[](numberOfPools);
InvestmentType pool;
// Loop through each Pool and each investment until sufficient available funds identified
// Looping is limited due to MAX_INVESTMENTS_PER_POOL and MAX_NUM_OF_POOLS
for (uint256 poolPtr = 0; poolPtr < numberOfPools; poolPtr++) {
pool = InvestmentType(poolPtr);
uint256 numOfInvestments = userInvestments[_user][pool].investments.length;
// check if _amount is available for redemption from this investment pool
for (uint256 i = 0; i < numOfInvestments; i++) {
if (userInvestments[_user][pool].investments[i].vestingTimestamp <= block.timestamp) {
priorAmount = availableToRedeem;
availableToRedeem = availableToRedeem.add(userInvestments[_user][pool].investments[i].amount);
poolRedemptionIndex[poolPtr] = i+1; // capture the highest entry +1 in each pool to redeem
if (availableToRedeem >= _amount) { // valid redemption achieved so process request
partRedemption = _amount.sub(priorAmount);
adjustedWeightedStake = processRedemption (_user, pool, partRedemption, poolRedemptionIndex);
return(adjustedWeightedStake);
}
} else {
break; // exit the loop if next entry timestamp beyond the current timestamp
}
}
}
// in the event that the redemption is not valid then leave the weighted stake unchanged
// calling code will need to use this to confirm if a redemption is ok
return(weightedStake[_user]);
}
function processRedemption (address _user, InvestmentType _type, uint256 _partRedemption, uint256[] memory _poolRedemptionIndex) private returns (uint256){
uint256 adjustedWeightedStake = weightedStake[_user];
uint lastPool = uint(_type);
// Iterate through each pool that will be used in the redemption removing redeemed entries and adjusting weightedStake
for (uint256 poolPtr = 0; poolPtr < lastPool + 1; poolPtr++) {
if(_poolRedemptionIndex[poolPtr] > 0){
adjustedWeightedStake = adjustedWeightedStake.sub(redeemThisPool(_user, poolPtr, lastPool, _poolRedemptionIndex[poolPtr]-1, _partRedemption));
}
}
weightedStake[_user] = adjustedWeightedStake;
return adjustedWeightedStake;
}
function redeemThisPool(address _user, uint _poolPtr, uint _lastPool, uint _lastIndex, uint256 _partRedemption) private returns(uint256){
uint256 redeemFromThisPool;
uint256 adjustedWeightedStake;
uint256 popFromStack = _lastIndex +1;
InvestmentType thisPool = InvestmentType(_poolPtr);
if(_poolPtr == _lastPool){
// last pool to be used in the redemption so check for part redemption of final element
if(_partRedemption != userInvestments[_user][thisPool].investments[_lastIndex].amount){
// part redemption of element at last position so adjust this element and pop one less element from the array
userInvestments[_user][thisPool].investments[_lastIndex].amount = userInvestments[_user][thisPool].investments[_lastIndex].amount.sub(_partRedemption);
redeemFromThisPool = _partRedemption;
adjustedWeightedStake = adjustedWeightedStake.add(weightAdjustment(_partRedemption,_user, thisPool, _lastIndex));
popFromStack = _lastIndex;
}
}
// now remove fully redeemed elements
uint iterations;
if (userInvestments[_user][thisPool].investments.length.sub(popFromStack) > popFromStack){
iterations = userInvestments[_user][thisPool].investments.length.sub(popFromStack);
} else {
iterations = popFromStack;
}
for (uint256 j = 0; j < iterations; j++) {
if (j < popFromStack) {
// adjust stake weighting for those elements that are being removed
redeemFromThisPool = redeemFromThisPool.add(userInvestments[_user][thisPool].investments[j].amount);
adjustedWeightedStake = adjustedWeightedStake.add(weightAdjustment(userInvestments[_user][thisPool].investments[j].amount,_user,thisPool,j));
}
if (j < userInvestments[_user][thisPool].investments.length - popFromStack){
// shift remaining array elements down stack to remove redeemed elements
userInvestments[_user][thisPool].investments[j] = userInvestments[_user][thisPool].investments[j+popFromStack];
}
}
// and resize the array
for (uint256 j = 0; j < popFromStack; j++) {
userInvestments[_user][thisPool].investments.pop();
}
userInvestments[_user][thisPool].total = userInvestments[_user][thisPool].total.sub(redeemFromThisPool);
return adjustedWeightedStake;
}
function weightAdjustment(uint256 _amount, address _user, InvestmentType _thisPool, uint _ptr ) private view returns(uint256) {
return (_amount.mul(userInvestments[_user][_thisPool].investments[_ptr].multiplier).div(ONE_HUNDRED_PCNT));
}
// Helper functions
function isValidInvestmentType(InvestmentType _type) internal pure returns (bool) {
return _type >= InvestmentType.Pool1 && _type <= InvestmentType.Pool10;
}
// getter functions
function getNumberOfInvestments(address _user, InvestmentType _type) external view returns(uint256) {
return userInvestments[_user][_type].investments.length;
}
function getUserInvestmentTotal(address _user, InvestmentType _type) external view returns(uint256) {
return userInvestments[_user][_type].total;
}
function getUserInvestments(address _user, InvestmentType _type) external view returns(Investment[] memory) {
return userInvestments[_user][_type].investments;
}
function getPresetMultipliers(InvestmentType _type) external view returns(uint256) {
return presetMultipliers[_type];
}
function getPresetDurations(InvestmentType _type) external view returns(uint256) {
return presetDurations[_type];
}
}
// File: contracts/MeridianMultiPoolStaking.sol
pragma solidity ^0.6.12;
contract MeridianMultiPoolStaking is InvestmentPools, ReentrancyGuard, CheckContract {
using SafeMath for uint256;
using SafeERC20 for IERC20;
// public constants and variables
uint constant public DECIMAL_PRECISION = 1e18;
uint constant public MAX_REWARD_TOKENS = 12;
IERC20 public MST;
bool public isInitialized;
bool public enableMultiPool;
uint256 public totalMSTStaked;
uint256 public totalOfWeightedStakes;
uint256 public currentRateIndex;
uint256 public lastRateSnapshotTimestamp; // used to track timestamp for interest calculations
mapping( address => bool) public auth; // authorized updaters
mapping( address => uint) public rewardsPerWeightedStake; // Running sum of rewardToken fees per-MST-staked
mapping( address => uint) public rewardTokenBalances; // latest contract balance for each reward token
address[] public rewardTokens;
mapping( address => uint) public mstStakes; // user actual tokens staked
mapping( address => uint) public weightedStakes; // user staked balances after uplift for lockup period
// snapshot of rewardsPerWeightedStake per user at point of last deposit/withdrawl User => token => value
mapping (address => mapping(address => uint)) public snapshots;
mapping(address => uint256[8]) public dailyRateSnapshots; // used to capture rewardsPerWeightedStake each day over 8 days for each reward token
// Events
event NewAuth(address _auth);
event RemoveAuth(address _auth);
event MultiPoolChanged(bool _setting);
event NewRewardToken(address _token);
event RemovedRewardToken(address _token);
event TotalMSTStakedUpdated(uint _totalMSTStaked);
event StakeChanged(address indexed staker, uint newStake);
event WeightedStakeChanged(address indexed staker, uint newStake);
event StakingGainsWithdrawn(address indexed staker, uint256[] userPendingRewards);
// authorized updaters of the rewards tracker
modifier onlyAuth() {
require(auth[msg.sender] == true, "MeridianStaking: Forbidden");
_;
}
// Governance functions
function initialize(address _mst) external onlyGov {
require(!isInitialized, "Already Initialized");
require (investmentsInitialized,"Must initialize investment pools first");
checkContract(_mst);
isInitialized = true;
MST = IERC20(_mst);
}
function setAuth(address _newAuth) external onlyGov {
require(_newAuth != address(0),"MeridianStaking: Invalid address");
auth[_newAuth] = true;
emit NewAuth(_newAuth);
}
function removeAuth(address _auth) external onlyGov {
require(_auth != address(0),"MeridianStaking: Invalid address");
delete auth[_auth];
emit RemoveAuth(_auth);
}
// Setting enableMultiPool allows investment across all pools rather than just the base pool
// if set to false the users can still withdraw from existing pools but can only stake to Pool1
function setMultiPool(bool _setting) external onlyGov {
enableMultiPool = _setting;
emit MultiPoolChanged(_setting);
}
function addRewardToken(address _token) external onlyGov {
checkContract(_token);
require(rewardTokens.length <= MAX_REWARD_TOKENS, "MeridianStaking: Too many reward tokens");
rewardTokens.push(_token);
emit NewRewardToken(_token);
}
function removeRewardToken(address _token) external onlyGov {
checkContract(_token);
IERC20 token = IERC20(_token);
require (token.balanceOf(address(this)) == 0,"MeridianStaking: Cannot remove token with non-zero rewards");
for (uint256 i = 0; i < rewardTokens.length; i++) {
if (rewardTokens[i] == _token) {
// Remove the address by shifting elements
for (uint256 j = i; j < rewardTokens.length - 1; j++) {
rewardTokens[j] = rewardTokens[j + 1];
}
// Resize the array by removing the last element
rewardTokens.pop();
// Remove the mapping entry
delete rewardsPerWeightedStake[_token];
emit RemovedRewardToken(_token);
break; // Exit the loop once the address is found and removed
}
}
}
// Core contract functions
function stakeMst(uint256 _amount, InvestmentType _type) external nonReentrant {
_stakeMst(msg.sender, _amount, _type);
}
function stakeMstOnBehalfOf(address _user, uint256 _amount, InvestmentType _type) external nonReentrant {
_stakeMst(_user, _amount, _type);
}
function _stakeMst(address _user, uint256 _amount, InvestmentType _type) internal {
require(isInitialized, "Contract not yet initialized");
require(_amount > 0,"MeridianStaking: Invalid stake");
require(enableMultiPool || _type == InvestmentType.Pool1, "MeridianStaking: Investment Pool not enabled");
// First update the rewards trakers to capture any rewards that have been sent to the contract since the last interaction
_increwardsPerWeightedStake();
uint256[] memory userPendingRewards;
uint currentWeightedStake = weightedStakes[_user];
if (currentWeightedStake != 0 ) {
userPendingRewards = _getUserPendingRewards(_user);
}
_updateUserSnapshots(_user);
uint256 newStake = StakeRequest(_user, _amount, _type);
// Increase user’s stake and total MST staked
totalOfWeightedStakes = totalOfWeightedStakes.add(newStake.sub(currentWeightedStake));
weightedStakes[_user] = newStake;
mstStakes[_user] = mstStakes[_user].add(_amount);
totalMSTStaked = totalMSTStaked.add(_amount);
emit TotalMSTStakedUpdated(totalMSTStaked);
require(MST.transferFrom(msg.sender, address(this), _amount),"Token transfer failed");
emit StakeChanged(_user, mstStakes[_user]);
emit WeightedStakeChanged(_user, newStake);
if (currentWeightedStake != 0 ) {
emit StakingGainsWithdrawn(_user, userPendingRewards);
_sendRewardsToUser(_user, userPendingRewards);
}
}
function unStakeMst(uint256 _amount) external nonReentrant {
require(isInitialized, "Contract not yet initialized");
require(_amount > 0,"MeridianStaking: Invalid amount");
// First update the rewards trakers to capture any rewards that have been sent to the contract since the last interaction
_increwardsPerWeightedStake();
uint MstToWithdraw = _amount < mstStakes[msg.sender] ? _amount : mstStakes[msg.sender];
uint currentWeightedStake = weightedStakes[msg.sender];
uint newStake = redemptionRequest(msg.sender, MstToWithdraw);
require(newStake < currentWeightedStake, "MeridianStaking: Insufficient funds available to redeem");
uint256[] memory userPendingRewards = _getUserPendingRewards(msg.sender);
_updateUserSnapshots(msg.sender);
// Decrease user's stake and total MST staked
totalOfWeightedStakes = totalOfWeightedStakes.sub(currentWeightedStake.sub(newStake));
weightedStakes[msg.sender] = newStake;
mstStakes[msg.sender] = mstStakes[msg.sender].sub(MstToWithdraw);
totalMSTStaked = totalMSTStaked.sub(MstToWithdraw);
emit TotalMSTStakedUpdated(totalMSTStaked);
// Transfer unstaked MST back to user
require(MST.transfer(msg.sender, MstToWithdraw),"MeridianStaking: Token transfer failed");
emit StakeChanged(msg.sender, mstStakes[msg.sender]);
emit WeightedStakeChanged(msg.sender, newStake);
emit StakingGainsWithdrawn(msg.sender, userPendingRewards);
_sendRewardsToUser(msg.sender, userPendingRewards);
}
function claimRewards() external nonReentrant {
require(isInitialized, "Contract not yet initialized");
// First update the rewards trakers to capture any rewards that have been sent to the contract since the last interaction
_increwardsPerWeightedStake();
uint currentWeightedStake = weightedStakes[msg.sender];
require(currentWeightedStake > 0, "MeridianStaking: User must have non-zero stake");
uint256[] memory userPendingRewards = _getUserPendingRewards(msg.sender);
_updateUserSnapshots(msg.sender);
emit StakingGainsWithdrawn(msg.sender, userPendingRewards);
_sendRewardsToUser(msg.sender, userPendingRewards);
}
// Helper functions
function _sendRewardsToUser(address _user, uint256[] memory _pendingRewards) private {
uint256 numOfRewardTokens = rewardTokens.length;
for (uint256 i = 0; i < numOfRewardTokens; i++) {
IERC20 token = IERC20(rewardTokens[i]);
uint256 currentBalance = token.balanceOf(address(this));
require(currentBalance >= _pendingRewards[i],"MeridianStaking: Insufficient contract balance");
require(rewardTokenBalances[rewardTokens[i]] >= _pendingRewards[i],"MeridianStaking: Insufficient rewards balance");
rewardTokenBalances[rewardTokens[i]] = rewardTokenBalances[rewardTokens[i]].sub(_pendingRewards[i]);
token.transfer(_user, _pendingRewards[i]);
}
}
function _updateUserSnapshots(address _user) private {
uint256 numOfRewardTokens = rewardTokens.length;
for (uint256 i = 0; i < numOfRewardTokens; i++) {
snapshots[_user][rewardTokens[i]] = rewardsPerWeightedStake[rewardTokens[i]];
}
}
// enables forced update of rewards tracker for better frontend balances sync
function increwardsPerWeightedStake() external onlyAuth {
_increwardsPerWeightedStake();
}
// Called at the start of every user contract call to update rewards tracker.
// For each reward token check if more rewards have been added since the last interaction
// if they have then update the rewardsPerWeightedStake accordingly
function _increwardsPerWeightedStake() private {
if (totalMSTStaked > 0) {
uint256 numOfRewardTokens = rewardTokens.length;
for (uint256 i = 0; i < numOfRewardTokens; i++) {
uint256 lastBalance = rewardTokenBalances[rewardTokens[i]];
IERC20 token = IERC20(rewardTokens[i]);
uint256 currentBalance = token.balanceOf(address(this));
// if tokens have been added since last interaction then update rewardsPerWeightedStake
if (currentBalance > lastBalance) {
uint256 newRewards = currentBalance.sub(lastBalance);
rewardsPerWeightedStake[rewardTokens[i]] = rewardsPerWeightedStake[rewardTokens[i]].add(newRewards.mul(DECIMAL_PRECISION).div(totalOfWeightedStakes));
rewardTokenBalances[rewardTokens[i]] = currentBalance;
}
}
_setDailySnapshots();
}
}
// Triggers once per day to create a circular buffer of 8 days of dailyRateSnapshots for the rewardsPerWeightedStakes
// dailyRateSnapshots can then be used externally to calculate the weekly change in snapshots
// dailyRateSnapshots[token][currentRateIndex % 8] - dailyRateSnapshots[token][(currentRateIndex + 1) % 8]
// and this can be used to approximate the interest rate for the frontend
function _setDailySnapshots() private {
if(block.timestamp >= lastRateSnapshotTimestamp + 1 days){
for (uint256 i = 0; i < rewardTokens.length; i++) {
dailyRateSnapshots[rewardTokens[i]][(currentRateIndex + 1) % 8] = rewardsPerWeightedStake[rewardTokens[i]];
}
lastRateSnapshotTimestamp = block.timestamp;
currentRateIndex = (currentRateIndex + 1) % 8;
}
}
// getter functions
function getMstStake(address _user) external view returns (uint256) {
return mstStakes[_user];
}
function getWeightedStake(address _user) external view returns (uint256) {
return weightedStakes[_user];
}
function getSnapshot(address _user,address _token ) external view returns (uint256) {
return snapshots[_user][_token];
}
function getRewardTokens() external view returns (address[] memory) {
return rewardTokens;
}
function getCurrentrewardPerWeightedStake(address _token) external view returns (uint256) {
return rewardsPerWeightedStake[_token];
}
function getDailyRateSnapshots(address _token) external view returns (uint256[8] memory) {
return dailyRateSnapshots[_token];
}
function getCurrentrewardsPerWeightedStake() external view returns (uint256[] memory) {
uint256 numOfRewardTokens = rewardTokens.length;
uint256[] memory returnArray = new uint256[](numOfRewardTokens);
for (uint256 i = 0; i < numOfRewardTokens; i++) {
address currentAddress = rewardTokens[i];
returnArray[i] = rewardsPerWeightedStake[currentAddress];
}
return returnArray;
}
function getRewardTokenBalance(address _token) external view returns (uint256) {
return rewardTokenBalances[_token];
}
function getRewardTokenBalances() external view returns (uint256[] memory) {
uint256 numOfRewardTokens = rewardTokens.length;
uint256[] memory returnArray = new uint256[](numOfRewardTokens);
for (uint256 i = 0; i < numOfRewardTokens; i++) {
address currentAddress = rewardTokens[i];
returnArray[i] = rewardTokenBalances[currentAddress];
}
return returnArray;
}
function getUserPendingRewards(address _account) external view returns (uint256[] memory) {
return _getUserPendingRewards(_account);
}
function _getUserPendingRewards(address _account) internal view returns (uint256[] memory) {
uint256 numOfRewardTokens = rewardTokens.length;
uint256[] memory returnArray = new uint256[](numOfRewardTokens);
for (uint256 i = 0; i < numOfRewardTokens; i++) {
returnArray[i] = _getPendingReward(_account,rewardTokens[i]);
}
return returnArray;
}
function getPendingReward(address _user, address _rewardToken) external view returns (uint) {
return _getPendingReward(_user, _rewardToken);
}
function _getPendingReward(address _user, address _rewardToken) internal view returns (uint) {
uint usersnapshot = snapshots[_user][_rewardToken];
uint pendingReward = weightedStakes[_user].mul(rewardsPerWeightedStake[_rewardToken].sub(usersnapshot)).div(DECIMAL_PRECISION);
return pendingReward;
}
function getIsAuthorizedUpdater (address _updater) external view returns(bool) {
return auth[_updater];
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_gov","type":"address"}],"name":"GovChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"_setting","type":"bool"}],"name":"MultiPoolChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_auth","type":"address"}],"name":"NewAuth","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_token","type":"address"}],"name":"NewRewardToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_auth","type":"address"}],"name":"RemoveAuth","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_token","type":"address"}],"name":"RemovedRewardToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"newStake","type":"uint256"}],"name":"StakeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"userPendingRewards","type":"uint256[]"}],"name":"StakingGainsWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_totalMSTStaked","type":"uint256"}],"name":"TotalMSTStakedUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"newStake","type":"uint256"}],"name":"WeightedStakeChanged","type":"event"},{"inputs":[],"name":"DECIMAL_PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_INVESTMENTS_PER_POOL","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_MULTIPLIER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_NUM_OF_POOLS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_REWARD_TOKENS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_MULTIPLIER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MST","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ONE_DAY_IN_SECONDS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ONE_HUNDRED_PCNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"addRewardToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_multiplier","type":"uint256"},{"internalType":"uint256","name":"_duration","type":"uint256"},{"internalType":"enum InvestmentPools.InvestmentType","name":"_pool","type":"uint8"}],"name":"adjustInvestment","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"auth","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentRateIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"dailyRateSnapshots","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enableMultiPool","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"getCurrentrewardPerWeightedStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentrewardsPerWeightedStake","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"getDailyRateSnapshots","outputs":[{"internalType":"uint256[8]","name":"","type":"uint256[8]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_updater","type":"address"}],"name":"getIsAuthorizedUpdater","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getMstStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"enum InvestmentPools.InvestmentType","name":"_type","type":"uint8"}],"name":"getNumberOfInvestments","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"address","name":"_rewardToken","type":"address"}],"name":"getPendingReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum InvestmentPools.InvestmentType","name":"_type","type":"uint8"}],"name":"getPresetDurations","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum InvestmentPools.InvestmentType","name":"_type","type":"uint8"}],"name":"getPresetMultipliers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"getRewardTokenBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRewardTokenBalances","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRewardTokens","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"address","name":"_token","type":"address"}],"name":"getSnapshot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"enum InvestmentPools.InvestmentType","name":"_type","type":"uint8"}],"name":"getUserInvestmentTotal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"enum InvestmentPools.InvestmentType","name":"_type","type":"uint8"}],"name":"getUserInvestments","outputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"multiplier","type":"uint256"},{"internalType":"uint256","name":"vestingTimestamp","type":"uint256"}],"internalType":"struct InvestmentPools.Investment[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getUserPendingRewards","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getWeightedStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gov","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"increwardsPerWeightedStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_mst","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"multipliers","type":"uint256[]"},{"internalType":"uint256[]","name":"durations","type":"uint256[]"}],"name":"initializeInvestments","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"investmentsInitialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isInitialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastRateSnapshotTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"mstStakes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numberOfPools","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum InvestmentPools.InvestmentType","name":"","type":"uint8"}],"name":"presetDurations","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum InvestmentPools.InvestmentType","name":"","type":"uint8"}],"name":"presetMultipliers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_auth","type":"address"}],"name":"removeAuth","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"removeRewardToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_renounce","type":"bool"}],"name":"renounceGov","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewardTokenBalances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewardsPerWeightedStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newAuth","type":"address"}],"name":"setAuth","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newGov","type":"address"}],"name":"setGov","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_setting","type":"bool"}],"name":"setMultiPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"snapshots","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"enum InvestmentPools.InvestmentType","name":"_type","type":"uint8"}],"name":"stakeMst","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"enum InvestmentPools.InvestmentType","name":"_type","type":"uint8"}],"name":"stakeMstOnBehalfOf","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalMSTStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalOfWeightedStakes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"unStakeMst","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"enum InvestmentPools.InvestmentType","name":"","type":"uint8"}],"name":"userInvestments","outputs":[{"internalType":"uint256","name":"total","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"weightedStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"weightedStakes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]Contract Creation Code
608060405234801561001057600080fd5b50600080546101003302610100600160a81b031990911617905560016006556141798061003e6000396000f3fe608060405234801561001057600080fd5b50600436106103ba5760003560e01c806385c7b427116101f4578063c4f59f9b1161011a578063e04664ca116100ad578063ed03e78c1161007c578063ed03e78c14610496578063fa6886ec14610779578063fbf6924e1461078c578063fe0f3a131461079f576103ba565b8063e04664ca14610743578063e10182b114610756578063e95f26981461075e578063ebc54c7c14610771576103ba565b8063cfad57a2116100e9578063cfad57a2146106f7578063d64efe9c1461070a578063da54c29d1461071d578063dd93e06a14610730576103ba565b8063c4f59f9b146106a9578063c9c313d9146106be578063cd5d2118146106d1578063cf7c11fa146106e4576103ba565b8063a905dbb011610192578063b4559d1011610161578063b4559d10146103fb578063b977965b1461066e578063bc825d2314610676578063c4d66de814610696576103ba565b8063a905dbb014610622578063aadcef8614610635578063b041337314610648578063b1f5de401461065b576103ba565b806390c87f13116101ce57806390c87f13146105e15780639e37c281146105f45780639e57dade14610607578063a20baee61461061a576103ba565b806385c7b427146105b357806389c23dba146105c65780638a5cc320146105d9576103ba565b8063392e53cd116102e45780636a8cb20f116102775780637bb7bed1116102465780637bb7bed1146105725780637ec475a8146105855780637f3fd918146105985780638281511c146105ab576103ba565b80636a8cb20f146105525780636f682a531461055a57806371860c4f146105625780637645ff1a1461056a576103ba565b80634d1df007116102b35780634d1df007146105275780635ce7b15f1461053a5780635d0cde97146105425780635d6a618d1461054a576103ba565b8063392e53cd146104d95780633d509c97146104ee5780633e40c5c6146105015780634cc4bc4114610514576103ba565b80631c03e6cc1161035c5780632a46d7251161032b5780632a46d725146104965780632b2e05c11461049e5780632d788644146104b1578063372500ab146104d1576103ba565b80631c03e6cc146104535780631e74d25714610466578063240dc9321461047b578063288f68661461048e576103ba565b806312d43a511161039857806312d43a511461040357806313a0c44314610418578063157d1c7e1461042b5780631b01df911461043e576103ba565b806307701cc3146103bf5780630ada74e9146103e85780630cec3148146103fb575b600080fd5b6103d26103cd36600461358c565b6107b2565b6040516103df919061412c565b60405180910390f35b6103d26103f6366004613712565b6107cd565b6103d26107df565b61040b6107e4565b6040516103df91906137ac565b6103d261042636600461358c565b6107f8565b6103d261043936600461358c565b61080a565b61045161044c36600461363c565b61081c565b005b61045161046136600461358c565b610862565b61046e610943565b6040516103df91906138d5565b6104516104893660046136da565b6109fa565b6103d2610a70565b6103d2610a76565b6104516104ac36600461358c565b610a7c565b6104c46104bf36600461358c565b610b24565b6040516103df91906138a3565b610451610b77565b6104e1610c67565b6040516103df919061390d565b6104516104fc36600461358c565b610c77565b6104e161050f36600461358c565b610e93565b6103d2610522366004613712565b610eb1565b6103d26105353660046135a7565b610ee4565b6103d2610f11565b6103d2610f17565b6103d2610f1c565b61046e610f22565b6103d2610fd2565b6104e1610fd8565b61040b610fe1565b61040b61058036600461372d565b610ff0565b6103d26105933660046135a7565b611017565b6104516105a636600461358c565b611034565b6104e16110d9565b6103d26105c136600461358c565b6110e9565b6103d26105d436600461358c565b6110fb565b6103d2611116565b6103d26105ef3660046135db565b61111d565b610451610602366004613679565b611165565b6103d261061536600461358c565b611394565b6103d26113af565b6103d2610630366004613712565b6113bb565b6103d261064336600461358c565b6113cd565b6103d26106563660046135db565b6113df565b61045161066936600461375d565b6113fc565b6103d261142f565b6106896106843660046135db565b611435565b6040516103df919061384a565b6104516106a436600461358c565b6114f4565b6106b16115a9565b6040516103df91906137fd565b6103d26106cc36600461358c565b61160b565b6104e16106df36600461358c565b611626565b61046e6106f236600461358c565b61163b565b61045161070536600461358c565b611646565b610451610718366004613780565b6116eb565b6103d261072b3660046135db565b611884565b6103d261073e36600461358c565b6118cf565b6104516107513660046136da565b6118e1565b6103d2611983565b6103d261076c366004613612565b611989565b6104516119ab565b61045161078736600461372d565b6119e9565b6103d261079a366004613712565b611cfb565b6103d26107ad3660046135a7565b611d0d565b6001600160a01b03166000908152600e602052604090205490565b60036020526000908152604090205481565b600a81565b60005461010090046001600160a01b031681565b600d6020526000908152604090205481565b60116020526000908152604090205481565b600260065414156108485760405162461bcd60e51b815260040161083f906140a7565b60405180910390fd5b6002600655610858838383611d20565b5050600160065550565b60005461010090046001600160a01b031633146108915760405162461bcd60e51b815260040161083f90613f0a565b61089a8161202c565b600f54600c10156108bd5760405162461bcd60e51b815260040161083f90613ec3565b600f80546001810182556000919091527f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac8020180546001600160a01b0319166001600160a01b0383161790556040517fc69f61e4bef149d13a9bb253756b4b6e0b1c2cd402efb69dfec416c6201d0bf1906109389083906137ac565b60405180910390a150565b600f54606090818167ffffffffffffffff8111801561096157600080fd5b5060405190808252806020026020018201604052801561098b578160200160208202803683370190505b50905060005b828110156109f3576000600f82815481106109a857fe5b60009182526020808320909101546001600160a01b0316808352600d9091526040909120548451919250908490849081106109df57fe5b602090810291909101015250600101610991565b5091505090565b60005461010090046001600160a01b03163314610a295760405162461bcd60e51b815260040161083f90613f0a565b6007805460ff60a81b1916600160a81b831515021790556040517ff07c2a5f22b138bfc567e9aa9624d0f15f436d28d49abe1c65e92a72c74a832e9061093890839061390d565b60095481565b6103e881565b60005461010090046001600160a01b03163314610aab5760405162461bcd60e51b815260040161083f90613f0a565b6001600160a01b038116610ad15760405162461bcd60e51b815260040161083f90613d63565b6001600160a01b0381166000908152600c602052604090819020805460ff19166001179055517f9f511455548a603e61f1cc70bb0a622d2ad70cb8b318198695efc90b5fce4e4c906109389083906137ac565b610b2c6134b4565b6001600160a01b0382166000908152601360205260409081902081516101008101928390529160089082845b815481526020019060010190808311610b585750505050509050919050565b60026006541415610b9a5760405162461bcd60e51b815260040161083f906140a7565b6002600655600754600160a01b900460ff16610bc85760405162461bcd60e51b815260040161083f90613b65565b610bd0612075565b3360009081526011602052604090205480610bfd5760405162461bcd60e51b815260040161083f90613e1f565b6060610c083361226a565b9050610c1333612312565b336001600160a01b03167f20236d1f813fa1fbd42714507db9d3f2ef3b56e82163c2f91f4df6aacefca6c582604051610c4c91906138d5565b60405180910390a2610c5e33826123a5565b50506001600655565b600754600160a01b900460ff1681565b60005461010090046001600160a01b03163314610ca65760405162461bcd60e51b815260040161083f90613f0a565b610caf8161202c565b6040516370a0823160e01b815281906001600160a01b038216906370a0823190610cdd9030906004016137ac565b60206040518083038186803b158015610cf557600080fd5b505afa158015610d09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d2d9190613745565b15610d4a5760405162461bcd60e51b815260040161083f90613ffd565b60005b600f54811015610e8e57826001600160a01b0316600f8281548110610d6e57fe5b6000918252602090912001546001600160a01b03161415610e8657805b600f5460001901811015610e0057600f8160010181548110610da957fe5b600091825260209091200154600f80546001600160a01b039092169183908110610dcf57fe5b600091825260209091200180546001600160a01b0319166001600160a01b0392909216919091179055600101610d8b565b50600f805480610e0c57fe5b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0385168252600d9052604080822091909155517fb5494e609b7d7189b9fd268eb38adea381bfc53fb5eeeab9dd8ecc3f8af9539e90610e799085906137ac565b60405180910390a1610e8e565b600101610d4d565b505050565b6001600160a01b03166000908152600c602052604090205460ff1690565b600060036000836009811115610ec357fe5b6009811115610ece57fe5b8152602001908152602001600020549050919050565b6001600160a01b038083166000908152601260209081526040808320938516835292905220545b92915050565b600b5481565b600c81565b610bb881565b600f54606090818167ffffffffffffffff81118015610f4057600080fd5b50604051908082528060200260200182016040528015610f6a578160200160208202803683370190505b50905060005b828110156109f3576000600f8281548110610f8757fe5b60009182526020808320909101546001600160a01b0316808352600e909152604090912054845191925090849084908110610fbe57fe5b602090810291909101015250600101610f70565b60015481565b60005460ff1681565b6007546001600160a01b031681565b600f8181548110610ffd57fe5b6000918252602090912001546001600160a01b0316905081565b601260209081526000928352604080842090915290825290205481565b60005461010090046001600160a01b031633146110635760405162461bcd60e51b815260040161083f90613f0a565b6001600160a01b0381166110895760405162461bcd60e51b815260040161083f90613d63565b6001600160a01b0381166000908152600c602052604090819020805460ff19169055517f54cba8c838ee951b9ccef4916ea25b653956ac3302498f6c4f28f0473ff4c583906109389083906137ac565b600754600160a81b900460ff1681565b600e6020526000908152604090205481565b6001600160a01b03166000908152600d602052604090205490565b6201518081565b6001600160a01b03821660009081526005602052604081208183600981111561114257fe5b600981111561114d57fe5b81526020810191909152604001600020549392505050565b60005461010090046001600160a01b031633146111945760405162461bcd60e51b815260040161083f90613f0a565b60005460ff16156111b75760405162461bcd60e51b815260040161083f90613ad1565b600a8251106111d85760405162461bcd60e51b815260040161083f90613e6d565b80518251146111f95760405162461bcd60e51b815260040161083f90613e95565b6000805460ff191660011781558080526103e87f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5560046020527f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ec8190555b8251811015611388576103e883828151811061127057fe5b60200260200101511015801561129b5750610bb883828151811061129057fe5b602002602001015111155b6112b75760405162461bcd60e51b815260040161083f90613afe565b60008282815181106112c557fe5b602002602001015110156112eb5760405162461bcd60e51b815260040161083f90613be2565b60006001820160098111156112fc57fe5b905083828151811061130a57fe5b60200260200101516003600083600981111561132257fe5b600981111561132d57fe5b81526020019081526020016000208190555082828151811061134b57fe5b60200260200101516004600083600981111561136357fe5b600981111561136e57fe5b815260208101919091526040016000205550600101611258565b50505160019081019055565b6001600160a01b031660009081526010602052604090205490565b670de0b6b3a764000081565b60046020526000908152604090205481565b60026020526000908152604090205481565b600560209081526000928352604080842090915290825290205481565b6002600654141561141f5760405162461bcd60e51b815260040161083f906140a7565b6002600655610c5e338383611d20565b600a5481565b6001600160a01b038216600090815260056020526040812060609183600981111561145c57fe5b600981111561146757fe5b8152602001908152602001600020600101805480602002602001604051908101604052809291908181526020016000905b828210156114e85783829060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505081526020019060010190611498565b50505050905092915050565b60005461010090046001600160a01b031633146115235760405162461bcd60e51b815260040161083f90613f0a565b600754600160a01b900460ff161561154d5760405162461bcd60e51b815260040161083f90613ad1565b60005460ff1661156f5760405162461bcd60e51b815260040161083f90613d98565b6115788161202c565b60078054600160a01b60ff60a01b19909116176001600160a01b0319166001600160a01b0392909216919091179055565b6060600f80548060200260200160405190810160405280929190818152602001828054801561160157602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116115e3575b5050505050905090565b6001600160a01b031660009081526011602052604090205490565b600c6020526000908152604090205460ff1681565b6060610f0b8261226a565b60005461010090046001600160a01b031633146116755760405162461bcd60e51b815260040161083f90613f0a565b6001600160a01b03811661169b5760405162461bcd60e51b815260040161083f90613d63565b60008054610100600160a81b0319166101006001600160a01b038416021790556040517f3b7bfe3d10f9653af5256b806dc7064214844fd6646f0606f57a58397d66b4cc906109389083906137ac565b60005461010090046001600160a01b0316331461171a5760405162461bcd60e51b815260040161083f90613f0a565b60005460ff1661173c5760405162461bcd60e51b815260040161083f906139d8565b61174581612634565b6117615760405162461bcd60e51b815260040161083f90613b35565b60015481600981111561177057fe5b111561178e5760405162461bcd60e51b815260040161083f90613fad565b6103e883101580156117a25750610bb88311155b6117be5760405162461bcd60e51b815260040161083f90613afe565b600460008260098111156117ce57fe5b60098111156117d957fe5b8152602001908152602001600020548210156118075760405162461bcd60e51b815260040161083f90613be2565b826003600083600981111561181857fe5b600981111561182357fe5b815260200190815260200160002081905550816004600083600981111561184657fe5b600981111561185157fe5b815260208101919091526040016000205560015481600981111561187157fe5b1415610e8e576001805481019055505050565b6001600160a01b0382166000908152600560205260408120818360098111156118a957fe5b60098111156118b457fe5b81526020810191909152604001600020600101549392505050565b60106020526000908152604090205481565b60005461010090046001600160a01b031633146119105760405162461bcd60e51b815260040161083f90613f0a565b6001811515146119325760405162461bcd60e51b815260040161083f90613b9c565b60008054610100600160a81b031916908190556040517f3b7bfe3d10f9653af5256b806dc7064214844fd6646f0606f57a58397d66b4cc91610938916101009091046001600160a01b0316906137ac565b60085481565b601360205281600052604060002081600881106119a257fe5b01549150829050565b336000908152600c602052604090205460ff1615156001146119df5760405162461bcd60e51b815260040161083f90613f0a565b6119e7612075565b565b60026006541415611a0c5760405162461bcd60e51b815260040161083f906140a7565b6002600655600754600160a01b900460ff16611a3a5760405162461bcd60e51b815260040161083f90613b65565b60008111611a5a5760405162461bcd60e51b815260040161083f90613c19565b611a62612075565b336000908152601060205260408120548210611a8d5733600090815260106020526040902054611a8f565b815b3360008181526011602052604081205492935090611aad9084612662565b9050818110611ace5760405162461bcd60e51b815260040161083f90613d06565b6060611ad93361226a565b9050611ae433612312565b611afa611af184846128c3565b600954906128c3565b6009553360009081526011602090815260408083208590556010909152902054611b2490856128c3565b33600090815260106020526040902055600854611b4190856128c3565b60088190556040517f39658f9da14624f3526fe2a3a57af76cafe8623274ef4cefb09a1f313be6241991611b749161412c565b60405180910390a160075460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb90611bae90339088906004016137e4565b602060405180830381600087803b158015611bc857600080fd5b505af1158015611bdc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c0091906136f6565b611c1c5760405162461bcd60e51b815260040161083f9061396b565b33600081815260106020526040908190205490517f39df0e5286a3ef2f42a0bf52f32cfe2c58e5b0405f47fe512f2c2439e4cfe20491611c5b9161412c565b60405180910390a2336001600160a01b03167ff743583723cf40a86b06c9242edf63fe465e613d29e9e58b2560aa3306bcef6b83604051611c9c919061412c565b60405180910390a2336001600160a01b03167f20236d1f813fa1fbd42714507db9d3f2ef3b56e82163c2f91f4df6aacefca6c582604051611cdd91906138d5565b60405180910390a2611cef33826123a5565b50506001600655505050565b600060046000836009811115610ec357fe5b6000611d198383612905565b9392505050565b600754600160a01b900460ff16611d495760405162461bcd60e51b815260040161083f90613b65565b60008211611d695760405162461bcd60e51b815260040161083f90613f41565b600754600160a81b900460ff1680611d8c57506000816009811115611d8a57fe5b145b611da85760405162461bcd60e51b815260040161083f90613a26565b611db0612075565b6001600160a01b0383166000908152601160205260409020546060908015611dde57611ddb8561226a565b91505b611de785612312565b6000611df486868661297f565b9050611e0c611e0382846128c3565b60095490612c72565b6009556001600160a01b03861660009081526011602090815260408083208490556010909152902054611e3f9086612c72565b6001600160a01b038716600090815260106020526040902055600854611e659086612c72565b60088190556040517f39658f9da14624f3526fe2a3a57af76cafe8623274ef4cefb09a1f313be6241991611e989161412c565b60405180910390a16007546040516323b872dd60e01b81526001600160a01b03909116906323b872dd90611ed490339030908a906004016137c0565b602060405180830381600087803b158015611eee57600080fd5b505af1158015611f02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f2691906136f6565b611f425760405162461bcd60e51b815260040161083f90613c87565b6001600160a01b038616600081815260106020526040908190205490517f39df0e5286a3ef2f42a0bf52f32cfe2c58e5b0405f47fe512f2c2439e4cfe20491611f8a9161412c565b60405180910390a2856001600160a01b03167ff743583723cf40a86b06c9242edf63fe465e613d29e9e58b2560aa3306bcef6b82604051611fcb919061412c565b60405180910390a2811561202457856001600160a01b03167f20236d1f813fa1fbd42714507db9d3f2ef3b56e82163c2f91f4df6aacefca6c58460405161201291906138d5565b60405180910390a261202486846123a5565b505050505050565b6001600160a01b0381166120525760405162461bcd60e51b815260040161083f90613c50565b803b806120715760405162461bcd60e51b815260040161083f90613f78565b5050565b600854156119e757600f5460005b8181101561225e576000600e6000600f848154811061209e57fe5b60009182526020808320909101546001600160a01b03168352820192909252604001812054600f805491935090849081106120d557fe5b60009182526020822001546040516370a0823160e01b81526001600160a01b03909116925082906370a08231906121109030906004016137ac565b60206040518083038186803b15801561212857600080fd5b505afa15801561213c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121609190613745565b90508281111561225357600061217682856128c3565b90506121de6121a260095461219c670de0b6b3a764000085612c9790919063ffffffff16565b90612cd1565b600d6000600f89815481106121b357fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205490612c72565b600d6000600f88815481106121ef57fe5b60009182526020808320909101546001600160a01b03168352820192909252604001812091909155600f80548492600e9290918990811061222c57fe5b60009182526020808320909101546001600160a01b03168352820192909252604001902055505b505050600101612083565b50612267612d13565b50565b600f54606090818167ffffffffffffffff8111801561228857600080fd5b506040519080825280602002602001820160405280156122b2578160200160208202803683370190505b50905060005b8281101561230a576122eb85600f83815481106122d157fe5b6000918252602090912001546001600160a01b0316612905565b8282815181106122f757fe5b60209081029190910101526001016122b8565b509392505050565b600f5460005b81811015610e8e57600d6000600f838154811061233157fe5b60009182526020808320909101546001600160a01b039081168452838201949094526040928301822054938716825260129052908120600f80549192918590811061237857fe5b60009182526020808320909101546001600160a01b03168352820192909252604001902055600101612318565b600f5460005b8181101561262e576000600f82815481106123c257fe5b60009182526020822001546040516370a0823160e01b81526001600160a01b03909116925082906370a08231906123fd9030906004016137ac565b60206040518083038186803b15801561241557600080fd5b505afa158015612429573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061244d9190613745565b905084838151811061245b57fe5b60200260200101518110156124825760405162461bcd60e51b815260040161083f906140de565b84838151811061248e57fe5b6020026020010151600e6000600f86815481106124a757fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205410156124ea5760405162461bcd60e51b815260040161083f9061405a565b61253d8584815181106124f957fe5b6020026020010151600e6000600f878154811061251257fe5b60009182526020808320909101546001600160a01b03168352820192909252604001902054906128c3565b600e6000600f868154811061254e57fe5b9060005260206000200160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200190815260200160002081905550816001600160a01b031663a9059cbb878786815181106125ac57fe5b60200260200101516040518363ffffffff1660e01b81526004016125d19291906137e4565b602060405180830381600087803b1580156125eb57600080fd5b505af11580156125ff573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061262391906136f6565b5050506001016123ab565b50505050565b60008082600981111561264357fe5b10158015610f0b5750600982600981111561265a57fe5b111592915050565b6000805460ff166126855760405162461bcd60e51b815260040161083f90613b65565b600082116126a55760405162461bcd60e51b815260040161083f90613a72565b600080600080606060015467ffffffffffffffff811180156126c657600080fd5b506040519080825280602002602001820160405280156126f0578160200160208202803683370190505b5090506000805b60015481101561289b5780600981111561270d57fe5b6001600160a01b038b166000908152600560205260408120919350908184600981111561273657fe5b600981111561274157fe5b815260200190815260200160002060010180549050905060005b81811015612891576001600160a01b038c166000908152600560205260408120429186600981111561278957fe5b600981111561279457fe5b815260200190815260200160002060010182815481106127b057fe5b90600052602060002090600302016002015411612884576001600160a01b038c1660009081526005602052604081208a9950612831918660098111156127f257fe5b60098111156127fd57fe5b8152602001908152602001600020600101828154811061281957fe5b60009182526020909120600390910201548a90612c72565b98508060010185848151811061284357fe5b6020026020010181815250508a891061287f576128608b896128c3565b955061286e8c858888612de5565b9950610f0b98505050505050505050565b612889565b612891565b60010161275b565b50506001016126f7565b5050506001600160a01b03871660009081526002602052604090205494505050505092915050565b6000611d1983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612e96565b6001600160a01b038083166000908152601260209081526040808320938516835292815282822054600d90915291812054909190829061297690670de0b6b3a76400009061219c9061295790866128c3565b6001600160a01b03891660009081526011602052604090205490612c97565b95945050505050565b6000805460ff166129a25760405162461bcd60e51b815260040161083f90613b65565b600083116129c25760405162461bcd60e51b815260040161083f906139b1565b6129cb82612634565b6129e75760405162461bcd60e51b815260040161083f90613b35565b6001600160a01b0384166000908152600560205260408120600a91846009811115612a0e57fe5b6009811115612a1957fe5b815260208101919091526040016000206001015410612a4a5760405162461bcd60e51b815260040161083f90613cb6565b6001600160a01b0384166000908152600560205260408120612a9791859190856009811115612a7557fe5b6009811115612a8057fe5b815260208101919091526040016000205490612c72565b6001600160a01b038516600090815260056020526040812090846009811115612abc57fe5b6009811115612ac757fe5b8152602001908152602001600020600001819055506000612b27612b2060046000866009811115612af457fe5b6009811115612aff57fe5b81526020019081526020016000205462015180612c9790919063ffffffff16565b4290612c72565b6001600160a01b0386166000908152600560205260408120919250846009811115612b4e57fe5b6009811115612b5957fe5b8152602001908152602001600020600101604051806060016040528086815260200160036000876009811115612b8b57fe5b6009811115612b9657fe5b8152602080820192909252604090810160009081205484529282018690528454600181810187559584528284208551600392830290910190815592850151958301959095559290920151600290920191909155612c4d91612c2e916103e89161219c91886009811115612c0557fe5b6009811115612c1057fe5b81526020019081526020016000205488612c9790919063ffffffff16565b6001600160a01b03871660009081526002602052604090205490612c72565b6001600160a01b03861660009081526002602052604090208190559150509392505050565b600082820183811015611d195760405162461bcd60e51b815260040161083f90613a9a565b600082612ca657506000610f0b565b82820282848281612cb357fe5b0414611d195760405162461bcd60e51b815260040161083f90613dde565b6000611d1983836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612ec2565b600b54620151800142106119e75760005b600f54811015612dd157600d6000600f8381548110612d3f57fe5b9060005260206000200160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020019081526020016000205460136000600f8481548110612d8f57fe5b60009182526020808320909101546001600160a01b031683528201929092526040019020600a546008906001010660088110612dc757fe5b0155600101612d24565b5042600b55600a5460089060010106600a55565b6001600160a01b03841660009081526002602052604081205481856009811115612e0b57fe5b905060005b81600101811015612e6f576000858281518110612e2957fe5b60200260200101511115612e6757612e64612e5d89838560018a8781518110612e4e57fe5b6020026020010151038b612ef9565b84906128c3565b92505b600101612e10565b50506001600160a01b03861660009081526002602052604090208190559050949350505050565b60008184841115612eba5760405162461bcd60e51b815260040161083f9190613918565b505050900390565b60008183612ee35760405162461bcd60e51b815260040161083f9190613918565b506000838581612eef57fe5b0495945050505050565b600080806001850181886009811115612f0e57fe5b905087891415613061576001600160a01b038a16600090815260056020526040812090826009811115612f3d57fe5b6009811115612f4857fe5b81526020019081526020016000206001018781548110612f6457fe5b9060005260206000209060030201600001548614613061576001600160a01b038a166000908152600560205260408120612fe591889190846009811115612fa757fe5b6009811115612fb257fe5b81526020019081526020016000206001018981548110612fce57fe5b6000918252602090912060039091020154906128c3565b6001600160a01b038b1660009081526005602052604081209083600981111561300a57fe5b600981111561301557fe5b8152602001908152602001600020600101888154811061303157fe5b600091825260209091206003909102015585935061305b613054858c848b61343b565b8490612c72565b92508691505b6001600160a01b038a16600090815260056020526040812083906130b39082908486600981111561308e57fe5b600981111561309957fe5b8152602081019190915260400160002060010154906128c3565b11156130eb576001600160a01b038b1660009081526005602052604081206130e49185919085600981111561308e57fe5b90506130ee565b50815b60005b8181101561331657838110156131e2576001600160a01b038c1660009081526005602052604081206131689185600981111561312957fe5b600981111561313457fe5b8152602001908152602001600020600101828154811061315057fe5b60009182526020909120600390910201548790612c72565b6001600160a01b038d1660009081526005602052604081209197506131df916131d89186600981111561319757fe5b60098111156131a257fe5b815260200190815260200160002060010183815481106131be57fe5b9060005260206000209060030201600001548e868561343b565b8690612c72565b94505b6001600160a01b038c166000908152600560205260408120859185600981111561320857fe5b600981111561321357fe5b81526020810191909152604001600020600101540381101561330e576001600160a01b038c1660009081526005602052604081209084600981111561325457fe5b600981111561325f57fe5b81526020019081526020016000206001018482018154811061327d57fe5b9060005260206000209060030201600560008e6001600160a01b03166001600160a01b0316815260200190815260200160002060008560098111156132be57fe5b60098111156132c957fe5b815260200190815260200160002060010182815481106132e557fe5b600091825260209091208254600390920201908155600180830154908201556002918201549101555b6001016130f1565b5060005b8381101561339d576001600160a01b038c1660009081526005602052604081209084600981111561334757fe5b600981111561335257fe5b815260200190815260200160002060010180548061336c57fe5b600082815260208120600360001990930192830201818155600181810183905560029091019190915591550161331a565b506001600160a01b038b1660009081526005602052604081206133eb918791908560098111156133c957fe5b60098111156133d457fe5b8152602081019190915260400160002054906128c3565b6001600160a01b038c1660009081526005602052604081209084600981111561341057fe5b600981111561341b57fe5b815260208101919091526040016000205550919998505050505050505050565b6001600160a01b0383166000908152600560205260408120612976906103e89061219c908487600981111561346c57fe5b600981111561347757fe5b8152602001908152602001600020600101858154811061349357fe5b90600052602060002090600302016001015488612c9790919063ffffffff16565b6040518061010001604052806008906020820280368337509192915050565b80356001600160a01b0381168114610f0b57600080fd5b600082601f8301126134fa578081fd5b813567ffffffffffffffff80821115613511578283fd5b60208083026040518282820101818110858211171561352e578687fd5b60405284815294508185019250858201818701830188101561354f57600080fd5b600091505b84821015613572578035845292820192600191909101908201613554565b505050505092915050565b8035600a8110610f0b57600080fd5b60006020828403121561359d578081fd5b611d1983836134d3565b600080604083850312156135b9578081fd5b6135c384846134d3565b91506135d284602085016134d3565b90509250929050565b600080604083850312156135ed578182fd5b82356001600160a01b0381168114613603578283fd5b91506135d2846020850161357d565b60008060408385031215613624578182fd5b61362e84846134d3565b946020939093013593505050565b600080600060608486031215613650578081fd5b61365a85856134d3565b925060208401359150613670856040860161357d565b90509250925092565b6000806040838503121561368b578182fd5b823567ffffffffffffffff808211156136a2578384fd5b6136ae868387016134ea565b935060208501359150808211156136c3578283fd5b506136d0858286016134ea565b9150509250929050565b6000602082840312156136eb578081fd5b8135611d1981614135565b600060208284031215613707578081fd5b8151611d1981614135565b600060208284031215613723578081fd5b611d19838361357d565b60006020828403121561373e578081fd5b5035919050565b600060208284031215613756578081fd5b5051919050565b6000806040838503121561376f578182fd5b823591506135d2846020850161357d565b600080600060608486031215613794578283fd5b8335925060208401359150613670856040860161357d565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b8181101561383e5783516001600160a01b031683529284019291840191600101613819565b50909695505050505050565b602080825282518282018190526000919060409081850190868401855b828110156138965781518051855286810151878601528501518585015260609093019290850190600101613867565b5091979650505050505050565b6101008101818360005b60088110156138cc5781518352602092830192909101906001016138ad565b50505092915050565b6020808252825182820181905260009190848201906040850190845b8181101561383e578351835292840192918401916001016138f1565b901515815260200190565b6000602080835283518082850152825b8181101561394457858101830151858201604001528201613928565b818111156139555783604083870101525b50601f01601f1916929092016040019392505050565b60208082526026908201527f4d6572696469616e5374616b696e673a20546f6b656e207472616e736665722060408201526519985a5b195960d21b606082015260800190565b6020808252600d908201526c496e76616c6964207374616b6560981b604082015260600190565b6020808252602e908201527f55736520696e697469616c697a65496e766573746d656e747320746f2066697260408201526d737420736574757020706f6f6c7360901b606082015260800190565b6020808252602c908201527f4d6572696469616e5374616b696e673a20496e766573746d656e7420506f6f6c60408201526b081b9bdd08195b98589b195960a21b606082015260800190565b6020808252600e908201526d125b9d985b1a5908185b5bdd5b9d60921b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b602080825260139082015272105b1c9958591e48125b9a5d1a585b1a5e9959606a1b604082015260600190565b6020808252601d908201527f496e76616c696420696e766573746d656e74206d756c7469706c696572000000604082015260600190565b602080825260169082015275496e76616c696420496e766573746d656e745479706560501b604082015260600190565b6020808252601c908201527f436f6e7472616374206e6f742079657420696e697469616c697a656400000000604082015260600190565b60208082526026908201527f4d6572696469616e5374616b696e673a2072656e6f756e6365206d757374206260408201526565207472756560d01b606082015260800190565b6020808252601b908201527f496e76616c696420696e766573746d656e74206475726174696f6e0000000000604082015260600190565b6020808252601f908201527f4d6572696469616e5374616b696e673a20496e76616c696420616d6f756e7400604082015260600190565b6020808252601e908201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604082015260600190565b602080825260159082015274151bdad95b881d1c985b9cd9995c8819985a5b1959605a1b604082015260600190565b60208082526030908201527f4d6178206e756d626572206f6620696e766573746d656e74732065786365656460408201526f195908199bdc881d1a1a5cc81c1bdbdb60821b606082015260800190565b60208082526037908201527f4d6572696469616e5374616b696e673a20496e73756666696369656e7420667560408201527f6e647320617661696c61626c6520746f2072656465656d000000000000000000606082015260800190565b6020808252818101527f4d6572696469616e5374616b696e673a20496e76616c69642061646472657373604082015260600190565b60208082526026908201527f4d75737420696e697469616c697a6520696e766573746d656e7420706f6f6c7360408201526508199a5c9cdd60d21b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252602e908201527f4d6572696469616e5374616b696e673a2055736572206d75737420686176652060408201526d6e6f6e2d7a65726f207374616b6560901b606082015260800190565b6020808252600e908201526d546f6f206d616e7920706f6f6c7360901b604082015260600190565b602080825260149082015273496e76616c696420696e7075742061727261797360601b604082015260600190565b60208082526027908201527f4d6572696469616e5374616b696e673a20546f6f206d616e792072657761726460408201526620746f6b656e7360c81b606082015260800190565b6020808252601a908201527f4d6572696469616e5374616b696e673a20466f7262696464656e000000000000604082015260600190565b6020808252601e908201527f4d6572696469616e5374616b696e673a20496e76616c6964207374616b650000604082015260600190565b6020808252818101527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604082015260600190565b60208082526030908201527f4e6f74206e65787420706f6f6c2e20506f6f6c73206d7573742062652073657460408201526f2075702073657175656e7469616c6c7960801b606082015260800190565b6020808252603a908201527f4d6572696469616e5374616b696e673a2043616e6e6f742072656d6f7665207460408201527f6f6b656e2077697468206e6f6e2d7a65726f2072657761726473000000000000606082015260800190565b6020808252602d908201527f4d6572696469616e5374616b696e673a20496e73756666696369656e7420726560408201526c77617264732062616c616e636560981b606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252602e908201527f4d6572696469616e5374616b696e673a20496e73756666696369656e7420636f60408201526d6e74726163742062616c616e636560901b606082015260800190565b90815260200190565b801515811461226757600080fdfea264697066735822122071f9d7de36bb6be53dc576498f0cdba64e39e59f2f31b3d93ba12cb1af148cc464736f6c634300060c0033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106103ba5760003560e01c806385c7b427116101f4578063c4f59f9b1161011a578063e04664ca116100ad578063ed03e78c1161007c578063ed03e78c14610496578063fa6886ec14610779578063fbf6924e1461078c578063fe0f3a131461079f576103ba565b8063e04664ca14610743578063e10182b114610756578063e95f26981461075e578063ebc54c7c14610771576103ba565b8063cfad57a2116100e9578063cfad57a2146106f7578063d64efe9c1461070a578063da54c29d1461071d578063dd93e06a14610730576103ba565b8063c4f59f9b146106a9578063c9c313d9146106be578063cd5d2118146106d1578063cf7c11fa146106e4576103ba565b8063a905dbb011610192578063b4559d1011610161578063b4559d10146103fb578063b977965b1461066e578063bc825d2314610676578063c4d66de814610696576103ba565b8063a905dbb014610622578063aadcef8614610635578063b041337314610648578063b1f5de401461065b576103ba565b806390c87f13116101ce57806390c87f13146105e15780639e37c281146105f45780639e57dade14610607578063a20baee61461061a576103ba565b806385c7b427146105b357806389c23dba146105c65780638a5cc320146105d9576103ba565b8063392e53cd116102e45780636a8cb20f116102775780637bb7bed1116102465780637bb7bed1146105725780637ec475a8146105855780637f3fd918146105985780638281511c146105ab576103ba565b80636a8cb20f146105525780636f682a531461055a57806371860c4f146105625780637645ff1a1461056a576103ba565b80634d1df007116102b35780634d1df007146105275780635ce7b15f1461053a5780635d0cde97146105425780635d6a618d1461054a576103ba565b8063392e53cd146104d95780633d509c97146104ee5780633e40c5c6146105015780634cc4bc4114610514576103ba565b80631c03e6cc1161035c5780632a46d7251161032b5780632a46d725146104965780632b2e05c11461049e5780632d788644146104b1578063372500ab146104d1576103ba565b80631c03e6cc146104535780631e74d25714610466578063240dc9321461047b578063288f68661461048e576103ba565b806312d43a511161039857806312d43a511461040357806313a0c44314610418578063157d1c7e1461042b5780631b01df911461043e576103ba565b806307701cc3146103bf5780630ada74e9146103e85780630cec3148146103fb575b600080fd5b6103d26103cd36600461358c565b6107b2565b6040516103df919061412c565b60405180910390f35b6103d26103f6366004613712565b6107cd565b6103d26107df565b61040b6107e4565b6040516103df91906137ac565b6103d261042636600461358c565b6107f8565b6103d261043936600461358c565b61080a565b61045161044c36600461363c565b61081c565b005b61045161046136600461358c565b610862565b61046e610943565b6040516103df91906138d5565b6104516104893660046136da565b6109fa565b6103d2610a70565b6103d2610a76565b6104516104ac36600461358c565b610a7c565b6104c46104bf36600461358c565b610b24565b6040516103df91906138a3565b610451610b77565b6104e1610c67565b6040516103df919061390d565b6104516104fc36600461358c565b610c77565b6104e161050f36600461358c565b610e93565b6103d2610522366004613712565b610eb1565b6103d26105353660046135a7565b610ee4565b6103d2610f11565b6103d2610f17565b6103d2610f1c565b61046e610f22565b6103d2610fd2565b6104e1610fd8565b61040b610fe1565b61040b61058036600461372d565b610ff0565b6103d26105933660046135a7565b611017565b6104516105a636600461358c565b611034565b6104e16110d9565b6103d26105c136600461358c565b6110e9565b6103d26105d436600461358c565b6110fb565b6103d2611116565b6103d26105ef3660046135db565b61111d565b610451610602366004613679565b611165565b6103d261061536600461358c565b611394565b6103d26113af565b6103d2610630366004613712565b6113bb565b6103d261064336600461358c565b6113cd565b6103d26106563660046135db565b6113df565b61045161066936600461375d565b6113fc565b6103d261142f565b6106896106843660046135db565b611435565b6040516103df919061384a565b6104516106a436600461358c565b6114f4565b6106b16115a9565b6040516103df91906137fd565b6103d26106cc36600461358c565b61160b565b6104e16106df36600461358c565b611626565b61046e6106f236600461358c565b61163b565b61045161070536600461358c565b611646565b610451610718366004613780565b6116eb565b6103d261072b3660046135db565b611884565b6103d261073e36600461358c565b6118cf565b6104516107513660046136da565b6118e1565b6103d2611983565b6103d261076c366004613612565b611989565b6104516119ab565b61045161078736600461372d565b6119e9565b6103d261079a366004613712565b611cfb565b6103d26107ad3660046135a7565b611d0d565b6001600160a01b03166000908152600e602052604090205490565b60036020526000908152604090205481565b600a81565b60005461010090046001600160a01b031681565b600d6020526000908152604090205481565b60116020526000908152604090205481565b600260065414156108485760405162461bcd60e51b815260040161083f906140a7565b60405180910390fd5b6002600655610858838383611d20565b5050600160065550565b60005461010090046001600160a01b031633146108915760405162461bcd60e51b815260040161083f90613f0a565b61089a8161202c565b600f54600c10156108bd5760405162461bcd60e51b815260040161083f90613ec3565b600f80546001810182556000919091527f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac8020180546001600160a01b0319166001600160a01b0383161790556040517fc69f61e4bef149d13a9bb253756b4b6e0b1c2cd402efb69dfec416c6201d0bf1906109389083906137ac565b60405180910390a150565b600f54606090818167ffffffffffffffff8111801561096157600080fd5b5060405190808252806020026020018201604052801561098b578160200160208202803683370190505b50905060005b828110156109f3576000600f82815481106109a857fe5b60009182526020808320909101546001600160a01b0316808352600d9091526040909120548451919250908490849081106109df57fe5b602090810291909101015250600101610991565b5091505090565b60005461010090046001600160a01b03163314610a295760405162461bcd60e51b815260040161083f90613f0a565b6007805460ff60a81b1916600160a81b831515021790556040517ff07c2a5f22b138bfc567e9aa9624d0f15f436d28d49abe1c65e92a72c74a832e9061093890839061390d565b60095481565b6103e881565b60005461010090046001600160a01b03163314610aab5760405162461bcd60e51b815260040161083f90613f0a565b6001600160a01b038116610ad15760405162461bcd60e51b815260040161083f90613d63565b6001600160a01b0381166000908152600c602052604090819020805460ff19166001179055517f9f511455548a603e61f1cc70bb0a622d2ad70cb8b318198695efc90b5fce4e4c906109389083906137ac565b610b2c6134b4565b6001600160a01b0382166000908152601360205260409081902081516101008101928390529160089082845b815481526020019060010190808311610b585750505050509050919050565b60026006541415610b9a5760405162461bcd60e51b815260040161083f906140a7565b6002600655600754600160a01b900460ff16610bc85760405162461bcd60e51b815260040161083f90613b65565b610bd0612075565b3360009081526011602052604090205480610bfd5760405162461bcd60e51b815260040161083f90613e1f565b6060610c083361226a565b9050610c1333612312565b336001600160a01b03167f20236d1f813fa1fbd42714507db9d3f2ef3b56e82163c2f91f4df6aacefca6c582604051610c4c91906138d5565b60405180910390a2610c5e33826123a5565b50506001600655565b600754600160a01b900460ff1681565b60005461010090046001600160a01b03163314610ca65760405162461bcd60e51b815260040161083f90613f0a565b610caf8161202c565b6040516370a0823160e01b815281906001600160a01b038216906370a0823190610cdd9030906004016137ac565b60206040518083038186803b158015610cf557600080fd5b505afa158015610d09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d2d9190613745565b15610d4a5760405162461bcd60e51b815260040161083f90613ffd565b60005b600f54811015610e8e57826001600160a01b0316600f8281548110610d6e57fe5b6000918252602090912001546001600160a01b03161415610e8657805b600f5460001901811015610e0057600f8160010181548110610da957fe5b600091825260209091200154600f80546001600160a01b039092169183908110610dcf57fe5b600091825260209091200180546001600160a01b0319166001600160a01b0392909216919091179055600101610d8b565b50600f805480610e0c57fe5b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0385168252600d9052604080822091909155517fb5494e609b7d7189b9fd268eb38adea381bfc53fb5eeeab9dd8ecc3f8af9539e90610e799085906137ac565b60405180910390a1610e8e565b600101610d4d565b505050565b6001600160a01b03166000908152600c602052604090205460ff1690565b600060036000836009811115610ec357fe5b6009811115610ece57fe5b8152602001908152602001600020549050919050565b6001600160a01b038083166000908152601260209081526040808320938516835292905220545b92915050565b600b5481565b600c81565b610bb881565b600f54606090818167ffffffffffffffff81118015610f4057600080fd5b50604051908082528060200260200182016040528015610f6a578160200160208202803683370190505b50905060005b828110156109f3576000600f8281548110610f8757fe5b60009182526020808320909101546001600160a01b0316808352600e909152604090912054845191925090849084908110610fbe57fe5b602090810291909101015250600101610f70565b60015481565b60005460ff1681565b6007546001600160a01b031681565b600f8181548110610ffd57fe5b6000918252602090912001546001600160a01b0316905081565b601260209081526000928352604080842090915290825290205481565b60005461010090046001600160a01b031633146110635760405162461bcd60e51b815260040161083f90613f0a565b6001600160a01b0381166110895760405162461bcd60e51b815260040161083f90613d63565b6001600160a01b0381166000908152600c602052604090819020805460ff19169055517f54cba8c838ee951b9ccef4916ea25b653956ac3302498f6c4f28f0473ff4c583906109389083906137ac565b600754600160a81b900460ff1681565b600e6020526000908152604090205481565b6001600160a01b03166000908152600d602052604090205490565b6201518081565b6001600160a01b03821660009081526005602052604081208183600981111561114257fe5b600981111561114d57fe5b81526020810191909152604001600020549392505050565b60005461010090046001600160a01b031633146111945760405162461bcd60e51b815260040161083f90613f0a565b60005460ff16156111b75760405162461bcd60e51b815260040161083f90613ad1565b600a8251106111d85760405162461bcd60e51b815260040161083f90613e6d565b80518251146111f95760405162461bcd60e51b815260040161083f90613e95565b6000805460ff191660011781558080526103e87f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff5560046020527f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ec8190555b8251811015611388576103e883828151811061127057fe5b60200260200101511015801561129b5750610bb883828151811061129057fe5b602002602001015111155b6112b75760405162461bcd60e51b815260040161083f90613afe565b60008282815181106112c557fe5b602002602001015110156112eb5760405162461bcd60e51b815260040161083f90613be2565b60006001820160098111156112fc57fe5b905083828151811061130a57fe5b60200260200101516003600083600981111561132257fe5b600981111561132d57fe5b81526020019081526020016000208190555082828151811061134b57fe5b60200260200101516004600083600981111561136357fe5b600981111561136e57fe5b815260208101919091526040016000205550600101611258565b50505160019081019055565b6001600160a01b031660009081526010602052604090205490565b670de0b6b3a764000081565b60046020526000908152604090205481565b60026020526000908152604090205481565b600560209081526000928352604080842090915290825290205481565b6002600654141561141f5760405162461bcd60e51b815260040161083f906140a7565b6002600655610c5e338383611d20565b600a5481565b6001600160a01b038216600090815260056020526040812060609183600981111561145c57fe5b600981111561146757fe5b8152602001908152602001600020600101805480602002602001604051908101604052809291908181526020016000905b828210156114e85783829060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505081526020019060010190611498565b50505050905092915050565b60005461010090046001600160a01b031633146115235760405162461bcd60e51b815260040161083f90613f0a565b600754600160a01b900460ff161561154d5760405162461bcd60e51b815260040161083f90613ad1565b60005460ff1661156f5760405162461bcd60e51b815260040161083f90613d98565b6115788161202c565b60078054600160a01b60ff60a01b19909116176001600160a01b0319166001600160a01b0392909216919091179055565b6060600f80548060200260200160405190810160405280929190818152602001828054801561160157602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116115e3575b5050505050905090565b6001600160a01b031660009081526011602052604090205490565b600c6020526000908152604090205460ff1681565b6060610f0b8261226a565b60005461010090046001600160a01b031633146116755760405162461bcd60e51b815260040161083f90613f0a565b6001600160a01b03811661169b5760405162461bcd60e51b815260040161083f90613d63565b60008054610100600160a81b0319166101006001600160a01b038416021790556040517f3b7bfe3d10f9653af5256b806dc7064214844fd6646f0606f57a58397d66b4cc906109389083906137ac565b60005461010090046001600160a01b0316331461171a5760405162461bcd60e51b815260040161083f90613f0a565b60005460ff1661173c5760405162461bcd60e51b815260040161083f906139d8565b61174581612634565b6117615760405162461bcd60e51b815260040161083f90613b35565b60015481600981111561177057fe5b111561178e5760405162461bcd60e51b815260040161083f90613fad565b6103e883101580156117a25750610bb88311155b6117be5760405162461bcd60e51b815260040161083f90613afe565b600460008260098111156117ce57fe5b60098111156117d957fe5b8152602001908152602001600020548210156118075760405162461bcd60e51b815260040161083f90613be2565b826003600083600981111561181857fe5b600981111561182357fe5b815260200190815260200160002081905550816004600083600981111561184657fe5b600981111561185157fe5b815260208101919091526040016000205560015481600981111561187157fe5b1415610e8e576001805481019055505050565b6001600160a01b0382166000908152600560205260408120818360098111156118a957fe5b60098111156118b457fe5b81526020810191909152604001600020600101549392505050565b60106020526000908152604090205481565b60005461010090046001600160a01b031633146119105760405162461bcd60e51b815260040161083f90613f0a565b6001811515146119325760405162461bcd60e51b815260040161083f90613b9c565b60008054610100600160a81b031916908190556040517f3b7bfe3d10f9653af5256b806dc7064214844fd6646f0606f57a58397d66b4cc91610938916101009091046001600160a01b0316906137ac565b60085481565b601360205281600052604060002081600881106119a257fe5b01549150829050565b336000908152600c602052604090205460ff1615156001146119df5760405162461bcd60e51b815260040161083f90613f0a565b6119e7612075565b565b60026006541415611a0c5760405162461bcd60e51b815260040161083f906140a7565b6002600655600754600160a01b900460ff16611a3a5760405162461bcd60e51b815260040161083f90613b65565b60008111611a5a5760405162461bcd60e51b815260040161083f90613c19565b611a62612075565b336000908152601060205260408120548210611a8d5733600090815260106020526040902054611a8f565b815b3360008181526011602052604081205492935090611aad9084612662565b9050818110611ace5760405162461bcd60e51b815260040161083f90613d06565b6060611ad93361226a565b9050611ae433612312565b611afa611af184846128c3565b600954906128c3565b6009553360009081526011602090815260408083208590556010909152902054611b2490856128c3565b33600090815260106020526040902055600854611b4190856128c3565b60088190556040517f39658f9da14624f3526fe2a3a57af76cafe8623274ef4cefb09a1f313be6241991611b749161412c565b60405180910390a160075460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb90611bae90339088906004016137e4565b602060405180830381600087803b158015611bc857600080fd5b505af1158015611bdc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c0091906136f6565b611c1c5760405162461bcd60e51b815260040161083f9061396b565b33600081815260106020526040908190205490517f39df0e5286a3ef2f42a0bf52f32cfe2c58e5b0405f47fe512f2c2439e4cfe20491611c5b9161412c565b60405180910390a2336001600160a01b03167ff743583723cf40a86b06c9242edf63fe465e613d29e9e58b2560aa3306bcef6b83604051611c9c919061412c565b60405180910390a2336001600160a01b03167f20236d1f813fa1fbd42714507db9d3f2ef3b56e82163c2f91f4df6aacefca6c582604051611cdd91906138d5565b60405180910390a2611cef33826123a5565b50506001600655505050565b600060046000836009811115610ec357fe5b6000611d198383612905565b9392505050565b600754600160a01b900460ff16611d495760405162461bcd60e51b815260040161083f90613b65565b60008211611d695760405162461bcd60e51b815260040161083f90613f41565b600754600160a81b900460ff1680611d8c57506000816009811115611d8a57fe5b145b611da85760405162461bcd60e51b815260040161083f90613a26565b611db0612075565b6001600160a01b0383166000908152601160205260409020546060908015611dde57611ddb8561226a565b91505b611de785612312565b6000611df486868661297f565b9050611e0c611e0382846128c3565b60095490612c72565b6009556001600160a01b03861660009081526011602090815260408083208490556010909152902054611e3f9086612c72565b6001600160a01b038716600090815260106020526040902055600854611e659086612c72565b60088190556040517f39658f9da14624f3526fe2a3a57af76cafe8623274ef4cefb09a1f313be6241991611e989161412c565b60405180910390a16007546040516323b872dd60e01b81526001600160a01b03909116906323b872dd90611ed490339030908a906004016137c0565b602060405180830381600087803b158015611eee57600080fd5b505af1158015611f02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f2691906136f6565b611f425760405162461bcd60e51b815260040161083f90613c87565b6001600160a01b038616600081815260106020526040908190205490517f39df0e5286a3ef2f42a0bf52f32cfe2c58e5b0405f47fe512f2c2439e4cfe20491611f8a9161412c565b60405180910390a2856001600160a01b03167ff743583723cf40a86b06c9242edf63fe465e613d29e9e58b2560aa3306bcef6b82604051611fcb919061412c565b60405180910390a2811561202457856001600160a01b03167f20236d1f813fa1fbd42714507db9d3f2ef3b56e82163c2f91f4df6aacefca6c58460405161201291906138d5565b60405180910390a261202486846123a5565b505050505050565b6001600160a01b0381166120525760405162461bcd60e51b815260040161083f90613c50565b803b806120715760405162461bcd60e51b815260040161083f90613f78565b5050565b600854156119e757600f5460005b8181101561225e576000600e6000600f848154811061209e57fe5b60009182526020808320909101546001600160a01b03168352820192909252604001812054600f805491935090849081106120d557fe5b60009182526020822001546040516370a0823160e01b81526001600160a01b03909116925082906370a08231906121109030906004016137ac565b60206040518083038186803b15801561212857600080fd5b505afa15801561213c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121609190613745565b90508281111561225357600061217682856128c3565b90506121de6121a260095461219c670de0b6b3a764000085612c9790919063ffffffff16565b90612cd1565b600d6000600f89815481106121b357fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205490612c72565b600d6000600f88815481106121ef57fe5b60009182526020808320909101546001600160a01b03168352820192909252604001812091909155600f80548492600e9290918990811061222c57fe5b60009182526020808320909101546001600160a01b03168352820192909252604001902055505b505050600101612083565b50612267612d13565b50565b600f54606090818167ffffffffffffffff8111801561228857600080fd5b506040519080825280602002602001820160405280156122b2578160200160208202803683370190505b50905060005b8281101561230a576122eb85600f83815481106122d157fe5b6000918252602090912001546001600160a01b0316612905565b8282815181106122f757fe5b60209081029190910101526001016122b8565b509392505050565b600f5460005b81811015610e8e57600d6000600f838154811061233157fe5b60009182526020808320909101546001600160a01b039081168452838201949094526040928301822054938716825260129052908120600f80549192918590811061237857fe5b60009182526020808320909101546001600160a01b03168352820192909252604001902055600101612318565b600f5460005b8181101561262e576000600f82815481106123c257fe5b60009182526020822001546040516370a0823160e01b81526001600160a01b03909116925082906370a08231906123fd9030906004016137ac565b60206040518083038186803b15801561241557600080fd5b505afa158015612429573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061244d9190613745565b905084838151811061245b57fe5b60200260200101518110156124825760405162461bcd60e51b815260040161083f906140de565b84838151811061248e57fe5b6020026020010151600e6000600f86815481106124a757fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190205410156124ea5760405162461bcd60e51b815260040161083f9061405a565b61253d8584815181106124f957fe5b6020026020010151600e6000600f878154811061251257fe5b60009182526020808320909101546001600160a01b03168352820192909252604001902054906128c3565b600e6000600f868154811061254e57fe5b9060005260206000200160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200190815260200160002081905550816001600160a01b031663a9059cbb878786815181106125ac57fe5b60200260200101516040518363ffffffff1660e01b81526004016125d19291906137e4565b602060405180830381600087803b1580156125eb57600080fd5b505af11580156125ff573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061262391906136f6565b5050506001016123ab565b50505050565b60008082600981111561264357fe5b10158015610f0b5750600982600981111561265a57fe5b111592915050565b6000805460ff166126855760405162461bcd60e51b815260040161083f90613b65565b600082116126a55760405162461bcd60e51b815260040161083f90613a72565b600080600080606060015467ffffffffffffffff811180156126c657600080fd5b506040519080825280602002602001820160405280156126f0578160200160208202803683370190505b5090506000805b60015481101561289b5780600981111561270d57fe5b6001600160a01b038b166000908152600560205260408120919350908184600981111561273657fe5b600981111561274157fe5b815260200190815260200160002060010180549050905060005b81811015612891576001600160a01b038c166000908152600560205260408120429186600981111561278957fe5b600981111561279457fe5b815260200190815260200160002060010182815481106127b057fe5b90600052602060002090600302016002015411612884576001600160a01b038c1660009081526005602052604081208a9950612831918660098111156127f257fe5b60098111156127fd57fe5b8152602001908152602001600020600101828154811061281957fe5b60009182526020909120600390910201548a90612c72565b98508060010185848151811061284357fe5b6020026020010181815250508a891061287f576128608b896128c3565b955061286e8c858888612de5565b9950610f0b98505050505050505050565b612889565b612891565b60010161275b565b50506001016126f7565b5050506001600160a01b03871660009081526002602052604090205494505050505092915050565b6000611d1983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612e96565b6001600160a01b038083166000908152601260209081526040808320938516835292815282822054600d90915291812054909190829061297690670de0b6b3a76400009061219c9061295790866128c3565b6001600160a01b03891660009081526011602052604090205490612c97565b95945050505050565b6000805460ff166129a25760405162461bcd60e51b815260040161083f90613b65565b600083116129c25760405162461bcd60e51b815260040161083f906139b1565b6129cb82612634565b6129e75760405162461bcd60e51b815260040161083f90613b35565b6001600160a01b0384166000908152600560205260408120600a91846009811115612a0e57fe5b6009811115612a1957fe5b815260208101919091526040016000206001015410612a4a5760405162461bcd60e51b815260040161083f90613cb6565b6001600160a01b0384166000908152600560205260408120612a9791859190856009811115612a7557fe5b6009811115612a8057fe5b815260208101919091526040016000205490612c72565b6001600160a01b038516600090815260056020526040812090846009811115612abc57fe5b6009811115612ac757fe5b8152602001908152602001600020600001819055506000612b27612b2060046000866009811115612af457fe5b6009811115612aff57fe5b81526020019081526020016000205462015180612c9790919063ffffffff16565b4290612c72565b6001600160a01b0386166000908152600560205260408120919250846009811115612b4e57fe5b6009811115612b5957fe5b8152602001908152602001600020600101604051806060016040528086815260200160036000876009811115612b8b57fe5b6009811115612b9657fe5b8152602080820192909252604090810160009081205484529282018690528454600181810187559584528284208551600392830290910190815592850151958301959095559290920151600290920191909155612c4d91612c2e916103e89161219c91886009811115612c0557fe5b6009811115612c1057fe5b81526020019081526020016000205488612c9790919063ffffffff16565b6001600160a01b03871660009081526002602052604090205490612c72565b6001600160a01b03861660009081526002602052604090208190559150509392505050565b600082820183811015611d195760405162461bcd60e51b815260040161083f90613a9a565b600082612ca657506000610f0b565b82820282848281612cb357fe5b0414611d195760405162461bcd60e51b815260040161083f90613dde565b6000611d1983836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612ec2565b600b54620151800142106119e75760005b600f54811015612dd157600d6000600f8381548110612d3f57fe5b9060005260206000200160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020019081526020016000205460136000600f8481548110612d8f57fe5b60009182526020808320909101546001600160a01b031683528201929092526040019020600a546008906001010660088110612dc757fe5b0155600101612d24565b5042600b55600a5460089060010106600a55565b6001600160a01b03841660009081526002602052604081205481856009811115612e0b57fe5b905060005b81600101811015612e6f576000858281518110612e2957fe5b60200260200101511115612e6757612e64612e5d89838560018a8781518110612e4e57fe5b6020026020010151038b612ef9565b84906128c3565b92505b600101612e10565b50506001600160a01b03861660009081526002602052604090208190559050949350505050565b60008184841115612eba5760405162461bcd60e51b815260040161083f9190613918565b505050900390565b60008183612ee35760405162461bcd60e51b815260040161083f9190613918565b506000838581612eef57fe5b0495945050505050565b600080806001850181886009811115612f0e57fe5b905087891415613061576001600160a01b038a16600090815260056020526040812090826009811115612f3d57fe5b6009811115612f4857fe5b81526020019081526020016000206001018781548110612f6457fe5b9060005260206000209060030201600001548614613061576001600160a01b038a166000908152600560205260408120612fe591889190846009811115612fa757fe5b6009811115612fb257fe5b81526020019081526020016000206001018981548110612fce57fe5b6000918252602090912060039091020154906128c3565b6001600160a01b038b1660009081526005602052604081209083600981111561300a57fe5b600981111561301557fe5b8152602001908152602001600020600101888154811061303157fe5b600091825260209091206003909102015585935061305b613054858c848b61343b565b8490612c72565b92508691505b6001600160a01b038a16600090815260056020526040812083906130b39082908486600981111561308e57fe5b600981111561309957fe5b8152602081019190915260400160002060010154906128c3565b11156130eb576001600160a01b038b1660009081526005602052604081206130e49185919085600981111561308e57fe5b90506130ee565b50815b60005b8181101561331657838110156131e2576001600160a01b038c1660009081526005602052604081206131689185600981111561312957fe5b600981111561313457fe5b8152602001908152602001600020600101828154811061315057fe5b60009182526020909120600390910201548790612c72565b6001600160a01b038d1660009081526005602052604081209197506131df916131d89186600981111561319757fe5b60098111156131a257fe5b815260200190815260200160002060010183815481106131be57fe5b9060005260206000209060030201600001548e868561343b565b8690612c72565b94505b6001600160a01b038c166000908152600560205260408120859185600981111561320857fe5b600981111561321357fe5b81526020810191909152604001600020600101540381101561330e576001600160a01b038c1660009081526005602052604081209084600981111561325457fe5b600981111561325f57fe5b81526020019081526020016000206001018482018154811061327d57fe5b9060005260206000209060030201600560008e6001600160a01b03166001600160a01b0316815260200190815260200160002060008560098111156132be57fe5b60098111156132c957fe5b815260200190815260200160002060010182815481106132e557fe5b600091825260209091208254600390920201908155600180830154908201556002918201549101555b6001016130f1565b5060005b8381101561339d576001600160a01b038c1660009081526005602052604081209084600981111561334757fe5b600981111561335257fe5b815260200190815260200160002060010180548061336c57fe5b600082815260208120600360001990930192830201818155600181810183905560029091019190915591550161331a565b506001600160a01b038b1660009081526005602052604081206133eb918791908560098111156133c957fe5b60098111156133d457fe5b8152602081019190915260400160002054906128c3565b6001600160a01b038c1660009081526005602052604081209084600981111561341057fe5b600981111561341b57fe5b815260208101919091526040016000205550919998505050505050505050565b6001600160a01b0383166000908152600560205260408120612976906103e89061219c908487600981111561346c57fe5b600981111561347757fe5b8152602001908152602001600020600101858154811061349357fe5b90600052602060002090600302016001015488612c9790919063ffffffff16565b6040518061010001604052806008906020820280368337509192915050565b80356001600160a01b0381168114610f0b57600080fd5b600082601f8301126134fa578081fd5b813567ffffffffffffffff80821115613511578283fd5b60208083026040518282820101818110858211171561352e578687fd5b60405284815294508185019250858201818701830188101561354f57600080fd5b600091505b84821015613572578035845292820192600191909101908201613554565b505050505092915050565b8035600a8110610f0b57600080fd5b60006020828403121561359d578081fd5b611d1983836134d3565b600080604083850312156135b9578081fd5b6135c384846134d3565b91506135d284602085016134d3565b90509250929050565b600080604083850312156135ed578182fd5b82356001600160a01b0381168114613603578283fd5b91506135d2846020850161357d565b60008060408385031215613624578182fd5b61362e84846134d3565b946020939093013593505050565b600080600060608486031215613650578081fd5b61365a85856134d3565b925060208401359150613670856040860161357d565b90509250925092565b6000806040838503121561368b578182fd5b823567ffffffffffffffff808211156136a2578384fd5b6136ae868387016134ea565b935060208501359150808211156136c3578283fd5b506136d0858286016134ea565b9150509250929050565b6000602082840312156136eb578081fd5b8135611d1981614135565b600060208284031215613707578081fd5b8151611d1981614135565b600060208284031215613723578081fd5b611d19838361357d565b60006020828403121561373e578081fd5b5035919050565b600060208284031215613756578081fd5b5051919050565b6000806040838503121561376f578182fd5b823591506135d2846020850161357d565b600080600060608486031215613794578283fd5b8335925060208401359150613670856040860161357d565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b8181101561383e5783516001600160a01b031683529284019291840191600101613819565b50909695505050505050565b602080825282518282018190526000919060409081850190868401855b828110156138965781518051855286810151878601528501518585015260609093019290850190600101613867565b5091979650505050505050565b6101008101818360005b60088110156138cc5781518352602092830192909101906001016138ad565b50505092915050565b6020808252825182820181905260009190848201906040850190845b8181101561383e578351835292840192918401916001016138f1565b901515815260200190565b6000602080835283518082850152825b8181101561394457858101830151858201604001528201613928565b818111156139555783604083870101525b50601f01601f1916929092016040019392505050565b60208082526026908201527f4d6572696469616e5374616b696e673a20546f6b656e207472616e736665722060408201526519985a5b195960d21b606082015260800190565b6020808252600d908201526c496e76616c6964207374616b6560981b604082015260600190565b6020808252602e908201527f55736520696e697469616c697a65496e766573746d656e747320746f2066697260408201526d737420736574757020706f6f6c7360901b606082015260800190565b6020808252602c908201527f4d6572696469616e5374616b696e673a20496e766573746d656e7420506f6f6c60408201526b081b9bdd08195b98589b195960a21b606082015260800190565b6020808252600e908201526d125b9d985b1a5908185b5bdd5b9d60921b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b602080825260139082015272105b1c9958591e48125b9a5d1a585b1a5e9959606a1b604082015260600190565b6020808252601d908201527f496e76616c696420696e766573746d656e74206d756c7469706c696572000000604082015260600190565b602080825260169082015275496e76616c696420496e766573746d656e745479706560501b604082015260600190565b6020808252601c908201527f436f6e7472616374206e6f742079657420696e697469616c697a656400000000604082015260600190565b60208082526026908201527f4d6572696469616e5374616b696e673a2072656e6f756e6365206d757374206260408201526565207472756560d01b606082015260800190565b6020808252601b908201527f496e76616c696420696e766573746d656e74206475726174696f6e0000000000604082015260600190565b6020808252601f908201527f4d6572696469616e5374616b696e673a20496e76616c696420616d6f756e7400604082015260600190565b6020808252601e908201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604082015260600190565b602080825260159082015274151bdad95b881d1c985b9cd9995c8819985a5b1959605a1b604082015260600190565b60208082526030908201527f4d6178206e756d626572206f6620696e766573746d656e74732065786365656460408201526f195908199bdc881d1a1a5cc81c1bdbdb60821b606082015260800190565b60208082526037908201527f4d6572696469616e5374616b696e673a20496e73756666696369656e7420667560408201527f6e647320617661696c61626c6520746f2072656465656d000000000000000000606082015260800190565b6020808252818101527f4d6572696469616e5374616b696e673a20496e76616c69642061646472657373604082015260600190565b60208082526026908201527f4d75737420696e697469616c697a6520696e766573746d656e7420706f6f6c7360408201526508199a5c9cdd60d21b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252602e908201527f4d6572696469616e5374616b696e673a2055736572206d75737420686176652060408201526d6e6f6e2d7a65726f207374616b6560901b606082015260800190565b6020808252600e908201526d546f6f206d616e7920706f6f6c7360901b604082015260600190565b602080825260149082015273496e76616c696420696e7075742061727261797360601b604082015260600190565b60208082526027908201527f4d6572696469616e5374616b696e673a20546f6f206d616e792072657761726460408201526620746f6b656e7360c81b606082015260800190565b6020808252601a908201527f4d6572696469616e5374616b696e673a20466f7262696464656e000000000000604082015260600190565b6020808252601e908201527f4d6572696469616e5374616b696e673a20496e76616c6964207374616b650000604082015260600190565b6020808252818101527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604082015260600190565b60208082526030908201527f4e6f74206e65787420706f6f6c2e20506f6f6c73206d7573742062652073657460408201526f2075702073657175656e7469616c6c7960801b606082015260800190565b6020808252603a908201527f4d6572696469616e5374616b696e673a2043616e6e6f742072656d6f7665207460408201527f6f6b656e2077697468206e6f6e2d7a65726f2072657761726473000000000000606082015260800190565b6020808252602d908201527f4d6572696469616e5374616b696e673a20496e73756666696369656e7420726560408201526c77617264732062616c616e636560981b606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252602e908201527f4d6572696469616e5374616b696e673a20496e73756666696369656e7420636f60408201526d6e74726163742062616c616e636560901b606082015260800190565b90815260200190565b801515811461226757600080fdfea264697066735822122071f9d7de36bb6be53dc576498f0cdba64e39e59f2f31b3d93ba12cb1af148cc464736f6c634300060c0033
Deployed Bytecode Sourcemap
37773:15332:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51328:132;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;25011:59;;;;;;:::i;:::-;;:::i;24298:42::-;;;:::i;24846:18::-;;;:::i;:::-;;;;;;;:::i;38467:56::-;;;;;;:::i;:::-;;:::i;38805:47::-;;;;;;:::i;:::-;;:::i;42451:155::-;;;;;;:::i;:::-;;:::i;:::-;;41040:282;;;;;;:::i;:::-;;:::i;50869:451::-;;;:::i;:::-;;;;;;;:::i;40883:149::-;;;;;;:::i;:::-;;:::i;38208:36::-;;;:::i;24416:44::-;;;:::i;40270:202::-;;;;;;:::i;:::-;;:::i;50720:141::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;45890:726::-;;;:::i;38104:25::-;;;:::i;:::-;;;;;;;:::i;41330:936::-;;;;;;:::i;:::-;;:::i;52983:119::-;;;;;;:::i;:::-;;:::i;37399:133::-;;;;;;:::i;:::-;;:::i;50309:134::-;;;;;;:::i;:::-;;:::i;38289:40::-;;;:::i;38026:43::-;;;:::i;24541:42::-;;;:::i;51468:436::-;;;:::i;24871:25::-;;;:::i;24805:34::-;;;:::i;38078:17::-;;;:::i;38689:29::-;;;;;;:::i;:::-;;:::i;39032:62::-;;;;;;:::i;:::-;;:::i;40480:196::-;;;;;;:::i;:::-;;:::i;38136:27::-;;;:::i;38581:52::-;;;;;;:::i;:::-;;:::i;50565:147::-;;;;;;:::i;:::-;;:::i;24749:47::-;;;:::i;37047:161::-;;;;;;:::i;:::-;;:::i;26364:1118::-;;;;;;:::i;:::-;;:::i;50059:110::-;;;;;;:::i;:::-;;:::i;37974:45::-;;;:::i;25077:57::-;;;;;;:::i;:::-;;:::i;24958:46::-;;;;;;:::i;:::-;;:::i;25455:88::-;;;;;;:::i;:::-;;:::i;42308:135::-;;;;;;:::i;:::-;;:::i;38251:31::-;;;:::i;37216:175::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;39969:293::-;;;;;;:::i;:::-;;:::i;50451:106::-;;;:::i;:::-;;;;;;;:::i;50181:120::-;;;;;;:::i;:::-;;:::i;38399:37::-;;;;;;:::i;:::-;;:::i;51912:148::-;;;;;;:::i;:::-;;:::i;25769:193::-;;;;;;:::i;:::-;;:::i;27490:859::-;;;;;;:::i;:::-;;:::i;36865:174::-;;;;;;:::i;:::-;;:::i;38725:42::-;;;;;;:::i;:::-;;:::i;25970:198::-;;;;;;:::i;:::-;;:::i;38172:29::-;;;:::i;39102:56::-;;;;;;:::i;:::-;;:::i;47797:104::-;;;:::i;44230:1652::-;;;;;;:::i;:::-;;:::i;37540:129::-;;;;;;:::i;:::-;;:::i;52481:156::-;;;;;;:::i;:::-;;:::i;51328:132::-;-1:-1:-1;;;;;51425:27:0;51398:7;51425:27;;;:19;:27;;;;;;;51328:132::o;25011:59::-;;;;;;;;;;;;;:::o;24298:42::-;24338:2;24298:42;:::o;24846:18::-;;;;;;-1:-1:-1;;;;;24846:18:0;;:::o;38467:56::-;;;;;;;;;;;;;:::o;38805:47::-;;;;;;;;;;;;;:::o;42451:155::-;2417:1;3023:7;;:19;;3015:63;;;;-1:-1:-1;;;3015:63:0;;;;;;;:::i;:::-;;;;;;;;;2417:1;3156:7;:18;42566:32:::1;42576:5:::0;42583:7;42592:5;42566:9:::1;:32::i;:::-;-1:-1:-1::0;;2373:1:0;3335:7;:22;-1:-1:-1;42451:155:0:o;41040:282::-;25707:3;;;;;-1:-1:-1;;;;;25707:3:0;25693:10;:17;25685:56;;;;-1:-1:-1;;;25685:56:0;;;;;;;:::i;:::-;41116:21:::1;41130:6;41116:13;:21::i;:::-;41156:12;:19:::0;38067:2:::1;-1:-1:-1::0;41156:40:0::1;41148:92;;;;-1:-1:-1::0;;;41148:92:0::1;;;;;;;:::i;:::-;41251:12;:25:::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;41251:25:0;;;;;::::1;::::0;;-1:-1:-1;;;;;;41251:25:0::1;-1:-1:-1::0;;;;;41251:25:0;::::1;;::::0;;41292:22:::1;::::0;::::1;::::0;::::1;::::0;41251:25;;41292:22:::1;:::i;:::-;;;;;;;;41040:282:::0;:::o;50869:451::-;50994:12;:19;50937:16;;;50994:19;51055:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;51055:32:0;;51024:63;;51103:9;51098:186;51122:17;51118:1;:21;51098:186;;;51161:22;51186:12;51199:1;51186:15;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;51186:15:0;51233:39;;;:23;:39;;;;;;;;51216:14;;51186:15;;-1:-1:-1;51233:39:0;51216:11;;51228:1;;51216:14;;;;;;;;;;;;;;;:56;-1:-1:-1;51141:3:0;;51098:186;;;-1:-1:-1;51301:11:0;-1:-1:-1;;50869:451:0;:::o;40883:149::-;25707:3;;;;;-1:-1:-1;;;;;25707:3:0;25693:10;:17;25685:56;;;;-1:-1:-1;;;25685:56:0;;;;;;;:::i;:::-;40956:15:::1;:26:::0;;-1:-1:-1;;;;40956:26:0::1;-1:-1:-1::0;;;40956:26:0;::::1;;;;::::0;;40998::::1;::::0;::::1;::::0;::::1;::::0;40956;;40998::::1;:::i;38208:36::-:0;;;;:::o;24416:44::-;24456:4;24416:44;:::o;40270:202::-;25707:3;;;;;-1:-1:-1;;;;;25707:3:0;25693:10;:17;25685:56;;;;-1:-1:-1;;;25685:56:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;40341:22:0;::::1;40333:66;;;;-1:-1:-1::0;;;40333:66:0::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;40410:14:0;::::1;;::::0;;;:4:::1;:14;::::0;;;;;;:21;;-1:-1:-1;;40410:21:0::1;40427:4;40410:21;::::0;;40447:17;::::1;::::0;::::1;::::0;40415:8;;40447:17:::1;:::i;50720:141::-:0;50790:17;;:::i;:::-;-1:-1:-1;;;;;50827:26:0;;;;;;:18;:26;;;;;;;50820:33;;;;;;;;;;;;50827:26;50820:33;;;;;;;;;;;;;;;;;;;;;;;;50720:141;;;:::o;45890:726::-;2417:1;3023:7;;:19;;3015:63;;;;-1:-1:-1;;;3015:63:0;;;;;;;:::i;:::-;2417:1;3156:7;:18;45960:13:::1;::::0;-1:-1:-1;;;45960:13:0;::::1;;;45952:54;;;;-1:-1:-1::0;;;45952:54:0::1;;;;;;;:::i;:::-;46151:29;:27;:29::i;:::-;46236:10;46193:25;46221:26:::0;;;:14:::1;:26;::::0;;;;;46266:24;46258:83:::1;;;;-1:-1:-1::0;;;46258:83:0::1;;;;;;;:::i;:::-;46352:35;46390:34;46413:10;46390:22;:34::i;:::-;46352:72;;46435:32;46456:10;46435:20;:32::i;:::-;46507:10;-1:-1:-1::0;;;;;46485:53:0::1;;46519:18;46485:53;;;;;;:::i;:::-;;;;;;;;46557:50;46576:10;46588:18;46557;:50::i;:::-;-1:-1:-1::0;;2373:1:0;3335:7;:22;45890:726::o;38104:25::-;;;-1:-1:-1;;;38104:25:0;;;;;:::o;41330:936::-;25707:3;;;;;-1:-1:-1;;;;;25707:3:0;25693:10;:17;25685:56;;;;-1:-1:-1;;;25685:56:0;;;;;;;:::i;:::-;41401:21:::1;41415:6;41401:13;:21::i;:::-;41482:30;::::0;-1:-1:-1;;;41482:30:0;;41455:6;;-1:-1:-1;;;;;41482:15:0;::::1;::::0;::::1;::::0;:30:::1;::::0;41506:4:::1;::::0;41482:30:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:35:::0;41473:106:::1;;;;-1:-1:-1::0;;;41473:106:0::1;;;;;;;:::i;:::-;41595:9;41590:669;41614:12;:19:::0;41610:23;::::1;41590:669;;;41678:6;-1:-1:-1::0;;;;;41659:25:0::1;:12;41672:1;41659:15;;;;;;;;;::::0;;;::::1;::::0;;;::::1;::::0;-1:-1:-1;;;;;41659:15:0::1;:25;41655:593;;;41782:1:::0;41765:134:::1;41789:12;:19:::0;-1:-1:-1;;41789:23:0;41785:27;::::1;41765:134;;;41860:12;41873:1;41877;41873:5;41860:19;;;;;;;;;::::0;;;::::1;::::0;;;::::1;::::0;41842:12:::1;:15:::0;;-1:-1:-1;;;;;41860:19:0;;::::1;::::0;41855:1;;41842:15;::::1;;;;;;::::0;;;::::1;::::0;;;::::1;:37:::0;;-1:-1:-1;;;;;;41842:37:0::1;-1:-1:-1::0;;;;;41842:37:0;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;41814:3:0::1;41765:134;;;;41983:12;:18;;;;;;;;::::0;;;::::1;::::0;;;;;-1:-1:-1;;41983:18:0;;;;;-1:-1:-1;;;;;;41983:18:0::1;::::0;;;;;;;;-1:-1:-1;;;;;42072:31:0;::::1;::::0;;:23:::1;:31:::0;;;;;;42065:38;;;;42127:26;::::1;::::0;::::1;::::0;42096:6;;42127:26:::1;:::i;:::-;;;;;;;;42172:5;;41655:593;41635:3;;41590:669;;;;25752:1;41330:936:::0;:::o;52983:119::-;-1:-1:-1;;;;;53080:14:0;53056:4;53080:14;;;:4;:14;;;;;;;;;52983:119::o;37399:133::-;37473:7;37500:17;:24;37518:5;37500:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;37493:31;;37399:133;;;:::o;50309:134::-;-1:-1:-1;;;;;50411:16:0;;;50384:7;50411:16;;;:9;:16;;;;;;;;:24;;;;;;;;;;50309:134;;;;;:::o;38289:40::-;;;;:::o;38026:43::-;38067:2;38026:43;:::o;24541:42::-;24579:4;24541:42;:::o;51468:436::-;51582:12;:19;51525:16;;;51582:19;51643:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;51643:32:0;;51612:63;;51691:9;51686:182;51710:17;51706:1;:21;51686:182;;;51749:22;51774:12;51787:1;51774:15;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;51774:15:0;51821:35;;;:19;:35;;;;;;;;51804:14;;51774:15;;-1:-1:-1;51821:35:0;51804:11;;51816:1;;51804:14;;;;;;;;;;;;;;;:52;-1:-1:-1;51729:3:0;;51686:182;;24871:25;;;;:::o;24805:34::-;;;;;;:::o;38078:17::-;;;-1:-1:-1;;;;;38078:17:0;;:::o;38689:29::-;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;38689:29:0;;-1:-1:-1;38689:29:0;:::o;39032:62::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;40480:196::-;25707:3;;;;;-1:-1:-1;;;;;25707:3:0;25693:10;:17;25685:56;;;;-1:-1:-1;;;25685:56:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;40551:19:0;::::1;40543:63;;;;-1:-1:-1::0;;;40543:63:0::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;40624:11:0;::::1;;::::0;;;:4:::1;:11;::::0;;;;;;40617:18;;-1:-1:-1;;40617:18:0::1;::::0;;40651:17;::::1;::::0;::::1;::::0;40629:5;;40651:17:::1;:::i;38136:27::-:0;;;-1:-1:-1;;;38136:27:0;;;;;:::o;38581:52::-;;;;;;;;;;;;;:::o;50565:147::-;-1:-1:-1;;;;;50673:31:0;50646:7;50673:31;;;:23;:31;;;;;;;50565:147::o;24749:47::-;24791:5;24749:47;:::o;37047:161::-;-1:-1:-1;;;;;37165:22:0;;37138:7;37165:22;;;:15;:22;;;;;37138:7;37188:5;37165:29;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;37165:29:0;:35;;37047:161;-1:-1:-1;;;37047:161:0:o;26364:1118::-;25707:3;;;;;-1:-1:-1;;;;;25707:3:0;25693:10;:17;25685:56;;;;-1:-1:-1;;;25685:56:0;;;;;;;:::i;:::-;26490:22:::1;::::0;::::1;;26489:23;26481:55;;;;-1:-1:-1::0;;;26481:55:0::1;;;;;;;:::i;:::-;24338:2;26555:11;:18;:37;26547:63;;;;-1:-1:-1::0;;;26547:63:0::1;;;;;;;:::i;:::-;26651:9;:16;26629:11;:18;:38;26621:71;;;;-1:-1:-1::0;;;26621:71:0::1;;;;;;;:::i;:::-;26705:22;:29:::0;;-1:-1:-1;;26705:29:0::1;26730:4;26705:29;::::0;;26745:39;;;24505:4:::1;26745:39:::0;:56;26840:15:::1;26745:39;26840:37:::0;;:41;;;26962:466:::1;26986:11;:18;26982:1;:22;26962:466;;;24505:4;27034:11;27046:1;27034:14;;;;;;;;;;;;;;:32;;:68;;;;;24579:4;27070:11;27082:1;27070:14;;;;;;;;;;;;;;:32;;27034:68;27026:110;;;;-1:-1:-1::0;;;27026:110:0::1;;;;;;;:::i;:::-;27175:1;27159:9;27169:1;27159:12;;;;;;;;;;;;;;:17;;27151:57;;;;-1:-1:-1::0;;;27151:57:0::1;;;;;;;:::i;:::-;27223:23;27300:1;27264:37:::0;::::1;27249:53;::::0;::::1;;;;;;27223:79;;27347:11;27359:1;27347:14;;;;;;;;;;;;;;27317:17;:27;27335:8;27317:27;;;;;;;;;;;;;;;;;;;;;;;;;;;:44;;;;27404:9;27414:1;27404:12;;;;;;;;;;;;;;27376:15;:25;27392:8;27376:25;;;;;;;;;;;;;;;;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;27376:25:0;:40;-1:-1:-1;27006:3:0::1;;26962:466;;;-1:-1:-1::0;;27454:18:0;27473:1:::1;27454:20:::0;;::::1;27438:36:::0;;26364:1118::o;50059:110::-;-1:-1:-1;;;;;50145:16:0;50118:7;50145:16;;;:9;:16;;;;;;;50059:110::o;37974:45::-;38015:4;37974:45;:::o;25077:57::-;;;;;;;;;;;;;:::o;24958:46::-;;;;;;;;;;;;;:::o;25455:88::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;42308:135::-;2417:1;3023:7;;:19;;3015:63;;;;-1:-1:-1;;;3015:63:0;;;;;;;:::i;:::-;2417:1;3156:7;:18;42398:37:::1;42408:10;42420:7:::0;42429:5;42398:9:::1;:37::i;38251:31::-:0;;;;:::o;37216:175::-;-1:-1:-1;;;;;37342:22:0;;;;;;:15;:22;;;;;37303:19;;37365:5;37342:29;;;;;;;;;;;;;;;;;;;;;;;;;;;:41;;37335:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37216:175;;;;:::o;39969:293::-;25707:3;;;;;-1:-1:-1;;;;;25707:3:0;25693:10;:17;25685:56;;;;-1:-1:-1;;;25685:56:0;;;;;;;:::i;:::-;40040:13:::1;::::0;-1:-1:-1;;;40040:13:0;::::1;;;40039:14;40031:46;;;;-1:-1:-1::0;;;40031:46:0::1;;;;;;;:::i;:::-;40097:22;::::0;::::1;;40088:73;;;;-1:-1:-1::0;;;40088:73:0::1;;;;;;;:::i;:::-;40172:19;40186:4;40172:13;:19::i;:::-;40202:13;:20:::0;;-1:-1:-1;;;;;;;40202:20:0;;::::1;;-1:-1:-1::0;;;;;;40233:18:0::1;-1:-1:-1::0;;;;;40233:18:0;;;::::1;::::0;;;::::1;::::0;;39969:293::o;50451:106::-;50501:16;50537:12;50530:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;50530:19:0;;;;;;;;;;;;;;;;;;;;;;;50451:106;:::o;50181:120::-;-1:-1:-1;;;;;50272:21:0;50245:7;50272:21;;;:14;:21;;;;;;;50181:120::o;38399:37::-;;;;;;;;;;;;;;;:::o;51912:148::-;51984:16;52020:32;52043:8;52020:22;:32::i;25769:193::-;25707:3;;;;;-1:-1:-1;;;;;25707:3:0;25693:10;:17;25685:56;;;;-1:-1:-1;;;25685:56:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;25838:21:0;::::1;25830:65;;;;-1:-1:-1::0;;;25830:65:0::1;;;;;;;:::i;:::-;25906:3;:13:::0;;-1:-1:-1;;;;;;25906:13:0::1;;-1:-1:-1::0;;;;;25906:13:0;::::1;;;::::0;;25935:19:::1;::::0;::::1;::::0;::::1;::::0;25906:13;;25935:19:::1;:::i;27490:859::-:0;25707:3;;;;;-1:-1:-1;;;;;25707:3:0;25693:10;:17;25685:56;;;;-1:-1:-1;;;25685:56:0;;;;;;;:::i;:::-;27614:22:::1;::::0;::::1;;27606:81;;;;-1:-1:-1::0;;;27606:81:0::1;;;;;;;:::i;:::-;27706:28;27728:5;27706:21;:28::i;:::-;27698:63;;;;-1:-1:-1::0;;;27698:63:0::1;;;;;;;:::i;:::-;27795:13;;27785:5;27780:11;;;;;;;;:28;;27772:88;;;;-1:-1:-1::0;;;27772:88:0::1;;;;;;;:::i;:::-;24505:4;27879:11;:29;;:62;;;;;24579:4;27912:11;:29;;27879:62;27871:104;;;;-1:-1:-1::0;;;27871:104:0::1;;;;;;;:::i;:::-;28112:15;:22;28128:5;28112:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;28099:9;:35;;28073:93;;;;-1:-1:-1::0;;;28073:93:0::1;;;;;;;:::i;:::-;28204:11;28177:17;:24;28195:5;28177:24;;;;;;;;;;;;;;;;;;;;;;;;;;;:38;;;;28251:9;28226:15;:22;28242:5;28226:22;;;;;;;;;;;;;;;;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;28226:22:0;:34;28290:13:::1;::::0;28280:5;28275:11:::1;::::0;::::1;;;;;;:28;28271:70;;;28322:13;::::0;;:17;::::1;28306:33:::0;;27490:859;;;:::o;36865:174::-;-1:-1:-1;;;;;36983:22:0;;36956:7;36983:22;;;:15;:22;;;;;36956:7;37006:5;36983:29;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;36983:29:0;:41;;:48;;36865:174;-1:-1:-1;;;36865:174:0:o;38725:42::-;;;;;;;;;;;;;:::o;25970:198::-;25707:3;;;;;-1:-1:-1;;;;;25707:3:0;25693:10;:17;25685:56;;;;-1:-1:-1;;;25685:56:0;;;;;;;:::i;:::-;26056:4:::1;26043:17:::0;::::1;;;26035:67;;;;-1:-1:-1::0;;;26035:67:0::1;;;;;;;:::i;:::-;26127:1;26113:16:::0;;-1:-1:-1;;;;;;26113:16:0::1;::::0;;;;26145:15:::1;::::0;::::1;::::0;::::1;::::0;26113:16:::1;26156:3:::0;;::::1;-1:-1:-1::0;;;;;26156:3:0::1;::::0;26145:15:::1;:::i;38172:29::-:0;;;;:::o;39102:56::-;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;39102:56:0;;-1:-1:-1;39102:56:0:o;47797:104::-;39860:10;39855:16;;;;:4;:16;;;;;;;;:24;;:16;:24;39847:63;;;;-1:-1:-1;;;39847:63:0;;;;;;;:::i;:::-;47864:29:::1;:27;:29::i;:::-;47797:104::o:0;44230:1652::-;2417:1;3023:7;;:19;;3015:63;;;;-1:-1:-1;;;3015:63:0;;;;;;;:::i;:::-;2417:1;3156:7;:18;44308:13:::1;::::0;-1:-1:-1;;;44308:13:0;::::1;;;44300:54;;;;-1:-1:-1::0;;;44300:54:0::1;;;;;;;:::i;:::-;44383:1;44373:7;:11;44365:54;;;;-1:-1:-1::0;;;44365:54:0::1;;;;;;;:::i;:::-;44561:29;:27;:29::i;:::-;44644:10;44603:18;44634:21:::0;;;:9:::1;:21;::::0;;;;;44624:31;::::1;:65;;44678:10;44668:21;::::0;;;:9:::1;:21;::::0;;;;;44624:65:::1;;;44658:7;44624:65;44743:10;44700:25;44728:26:::0;;;:14:::1;:26;::::0;;;;;44603:86;;-1:-1:-1;44700:25:0;44781:44:::1;::::0;44603:86;44781:17:::1;:44::i;:::-;44765:60;;44855:20;44844:8;:31;44836:99;;;;-1:-1:-1::0;;;44836:99:0::1;;;;;;;:::i;:::-;44948:35;44986:34;45009:10;44986:22;:34::i;:::-;44948:72;;45031:32;45052:10;45031:20;:32::i;:::-;45155:61;45181:34;:20:::0;45206:8;45181:24:::1;:34::i;:::-;45155:21;::::0;;:25:::1;:61::i;:::-;45131:21;:85:::0;45242:10:::1;45227:26;::::0;;;:14:::1;:26;::::0;;;;;;;:37;;;45299:9:::1;:21:::0;;;;;;:40:::1;::::0;45325:13;45299:25:::1;:40::i;:::-;45285:10;45275:21;::::0;;;:9:::1;:21;::::0;;;;:64;45367:14:::1;::::0;:33:::1;::::0;45386:13;45367:18:::1;:33::i;:::-;45350:14;:50:::0;;;45426:37:::1;::::0;::::1;::::0;::::1;::::0;::::1;:::i;:::-;;;;;;;;45531:3;::::0;:39:::1;::::0;-1:-1:-1;;;45531:39:0;;-1:-1:-1;;;;;45531:3:0;;::::1;::::0;:12:::1;::::0;:39:::1;::::0;45544:10:::1;::::0;45556:13;;45531:39:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;45523:89;;;;-1:-1:-1::0;;;45523:89:0::1;;;;;;;:::i;:::-;45641:10;45653:21;::::0;;;:9:::1;:21;::::0;;;;;;;45628:47;;::::1;::::0;::::1;::::0;::::1;:::i;:::-;;;;;;;;45712:10;-1:-1:-1::0;;;;;45691:42:0::1;;45724:8;45691:42;;;;;;:::i;:::-;;;;;;;;45773:10;-1:-1:-1::0;;;;;45751:53:0::1;;45785:18;45751:53;;;;;;:::i;:::-;;;;;;;;45823:50;45842:10;45854:18;45823;:50::i;:::-;-1:-1:-1::0;;2373:1:0;3335:7;:22;-1:-1:-1;;;44230:1652:0:o;37540:129::-;37612:7;37639:15;:22;37655:5;37639:22;;;;;;;52481:156;52567:4;52591:38;52609:5;52616:12;52591:17;:38::i;:::-;52584:45;52481:156;-1:-1:-1;;;52481:156:0:o;42614:1608::-;42715:13;;-1:-1:-1;;;42715:13:0;;;;42707:54;;;;-1:-1:-1;;;42707:54:0;;;;;;;:::i;:::-;42790:1;42780:7;:11;42772:53;;;;-1:-1:-1;;;42772:53:0;;;;;;;:::i;:::-;42844:15;;-1:-1:-1;;;42844:15:0;;;;;:48;;-1:-1:-1;42872:20:0;42863:5;:29;;;;;;;;;42844:48;42836:105;;;;-1:-1:-1;;;42836:105:0;;;;;;;:::i;:::-;43083:29;:27;:29::i;:::-;-1:-1:-1;;;;;43199:21:0;;43171:25;43199:21;;;:14;:21;;;;;;43125:35;;43235:25;;43231:109;;43299:29;43322:5;43299:22;:29::i;:::-;43278:50;;43231:109;43350:27;43371:5;43350:20;:27::i;:::-;43388:16;43407:35;43420:5;43427:7;43436:5;43407:12;:35::i;:::-;43388:54;-1:-1:-1;43536:61:0;43562:34;43388:54;43575:20;43562:12;:34::i;:::-;43536:21;;;:25;:61::i;:::-;43512:21;:85;-1:-1:-1;;;;;43608:21:0;;;;;;:14;:21;;;;;;;;:32;;;43670:9;:16;;;;;;:29;;43691:7;43670:20;:29::i;:::-;-1:-1:-1;;;;;43651:16:0;;;;;;:9;:16;;;;;:48;43727:14;;:27;;43746:7;43727:18;:27::i;:::-;43710:14;:44;;;43770:37;;;;;;;:::i;:::-;;;;;;;;43828:3;;:52;;-1:-1:-1;;;43828:52:0;;-1:-1:-1;;;;;43828:3:0;;;;:16;;:52;;43845:10;;43865:4;;43872:7;;43828:52;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;43820:85;;;;-1:-1:-1;;;43820:85:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;43921:37:0;;43941:16;;;;:9;:16;;;;;;;;43921:37;;;;;;;:::i;:::-;;;;;;;;43995:5;-1:-1:-1;;;;;43974:37:0;;44002:8;43974:37;;;;;;:::i;:::-;;;;;;;;44044:25;;44040:172;;44114:5;-1:-1:-1;;;;;44092:48:0;;44121:18;44092:48;;;;;;:::i;:::-;;;;;;;;44155:45;44174:5;44181:18;44155;:45::i;:::-;42614:1608;;;;;;:::o;352:337::-;-1:-1:-1;;;;;426:22:0;;418:65;;;;-1:-1:-1;;;418:65:0;;;;;;;:::i;:::-;595:21;;636:8;628:53;;;;-1:-1:-1;;;628:53:0;;;;;;;:::i;:::-;352:337;;:::o;48160:985::-;48222:14;;:18;48218:920;;48285:12;:19;48257:25;48319:773;48343:17;48339:1;:21;48319:773;;;48386:19;48408;:36;48428:12;48441:1;48428:15;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;48428:15:0;48408:36;;;;;;;;;;;;;48485:12;:15;;48408:36;;-1:-1:-1;48485:12:0;48498:1;;48485:15;;;;;;;;;;;;;;;48545:30;;-1:-1:-1;;;48545:30:0;;-1:-1:-1;;;;;48485:15:0;;;;-1:-1:-1;48485:15:0;;48545;;:30;;48569:4;;48545:30;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;48520:55;;48720:11;48703:14;:28;48699:378;;;48757:18;48778:31;:14;48797:11;48778:18;:31::i;:::-;48757:52;;48875:106;48920:60;48958:21;;48920:33;38015:4;48920:10;:14;;:33;;;;:::i;:::-;:37;;:60::i;:::-;48875:23;:40;48899:12;48912:1;48899:15;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;48899:15:0;48875:40;;;;;;;;;;;;;;:44;:106::i;:::-;48832:23;:40;48856:12;48869:1;48856:15;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;48856:15:0;48832:40;;;;;;;;;;;;:149;;;;49024:12;:15;;49043:14;;49004:19;;48856:15;;49037:1;;49024:15;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;49024:15:0;49004:36;;;;;;;;;;;;:53;-1:-1:-1;48699:378:0;-1:-1:-1;;;48362:3:0;;48319:773;;;;49106:20;:18;:20::i;:::-;48218:920;48160:985::o;52068:405::-;52198:12;:19;52141:16;;;52198:19;52259:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;52259:32:0;;52228:63;;52307:9;52302:135;52326:17;52322:1;:21;52302:135;;;52382:43;52400:8;52409:12;52422:1;52409:15;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;52409:15:0;52382:17;:43::i;:::-;52365:11;52377:1;52365:14;;;;;;;;;;;;;;;;;:60;52345:3;;52302:135;;;-1:-1:-1;52454:11:0;52068:405;-1:-1:-1;;;52068:405:0:o;47426:280::-;47518:12;:19;47490:25;47548:151;47572:17;47568:1;:21;47548:151;;;47647:23;:40;47671:12;47684:1;47671:15;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;47671:15:0;;;47647:40;;;;;;;;;;;;;;;;47611:16;;;;;:9;:16;;;;;47628:12;:15;;47611:16;;47671:15;47641:1;;47628:15;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;47628:15:0;47611:33;;;;;;;;;;;;:76;47628:15;47591:3;47548:151;;46653:765;46777:12;:19;46749:25;46807:604;46831:17;46827:1;:21;46807:604;;;46870:12;46892;46905:1;46892:15;;;;;;;;;;;;;;;;;46948:30;;-1:-1:-1;;;46948:30:0;;-1:-1:-1;;;;;46892:15:0;;;;-1:-1:-1;46892:15:0;;46948;;:30;;46972:4;;46948:30;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;46923:55;;47019:15;47035:1;47019:18;;;;;;;;;;;;;;47001:14;:36;;46993:94;;;;-1:-1:-1;;;46993:94:0;;;;;;;:::i;:::-;47162:15;47178:1;47162:18;;;;;;;;;;;;;;47122:19;:36;47142:12;47155:1;47142:15;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;47142:15:0;47122:36;;;;;;;;;;;;;:58;;47114:115;;;;-1:-1:-1;;;47114:115:0;;;;;;;:::i;:::-;47283:60;47324:15;47340:1;47324:18;;;;;;;;;;;;;;47283:19;:36;47303:12;47316:1;47303:15;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;47303:15:0;47283:36;;;;;;;;;;;;;;:40;:60::i;:::-;47244:19;:36;47264:12;47277:1;47264:15;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;47264:15:0;-1:-1:-1;;;;;47244:36:0;-1:-1:-1;;;;;47244:36:0;;;;;;;;;;;;:99;;;;47358:5;-1:-1:-1;;;;;47358:14:0;;47373:5;47380:15;47396:1;47380:18;;;;;;;;;;;;;;47358:41;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;46850:3:0;;46807:604;;;;46653:765;;;:::o;36655:175::-;36731:4;;36759:5;:29;;;;;;;;;;:63;;;;-1:-1:-1;36801:21:0;36792:5;:30;;;;;;;;;;;36655:175;-1:-1:-1;;36655:175:0:o;30675:2194::-;30752:7;30780:22;;;;30772:63;;;;-1:-1:-1;;;30772:63:0;;;;;;;:::i;:::-;30864:1;30854:7;:11;30846:37;;;;-1:-1:-1;;;30846:37:0;;;;;;;:::i;:::-;30902:25;30938:19;30968:29;31009:22;31042:36;31095:13;;31081:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;31081:28:0;-1:-1:-1;31042:67:0;-1:-1:-1;31120:19:0;;31333:1312;31369:13;;31359:7;:23;31333:1312;;;31432:7;31417:23;;;;;;;;-1:-1:-1;;;;;31482:22:0;;31455:24;31482:22;;;:15;:22;;;;;31410:30;;-1:-1:-1;31455:24:0;;31410:30;31482:28;;;;;;;;;;;;;;;;;;;;;;;;;;;:40;;:47;;;;31455:74;;31636:9;31631:1003;31655:16;31651:1;:20;31631:1003;;;-1:-1:-1;;;;;31701:22:0;;;;;;:15;:22;;;;;31765:15;;31724:4;31701:28;;;;;;;;;;;;;;;;;;;;;;;;;;;:40;;31742:1;31701:43;;;;;;;;;;;;;;;;;;:60;;;:79;31697:922;;-1:-1:-1;;;;;31917:22:0;;;;;;:15;:22;;;;;31821:17;;-1:-1:-1;31895:73:0;;31940:4;31917:28;;;;;;;;;;;;;;;;;;;;;;;;;;;:40;;31958:1;31917:43;;;;;;;;;;;;;;;;;;;;;:50;31895:17;;:21;:73::i;:::-;31875:93;;32022:1;32024;32022:3;31991:19;32011:7;31991:28;;;;;;;;;;;;;:34;;;;;32130:7;32109:17;:28;32105:370;;32231:24;:7;32243:11;32231;:24::i;:::-;32214:41;;32306:68;32325:5;32332:4;32338:14;32354:19;32306:17;:68::i;:::-;32282:92;-1:-1:-1;32422:29:0;;-1:-1:-1;;;;;;;;;32422:29:0;32105:370;31697:922;;;32523:5;;31697:922;31673:3;;31631:1003;;;-1:-1:-1;;31384:9:0;;31333:1312;;;-1:-1:-1;;;;;;;;32840:20:0;;;;;;:13;:20;;;;;;;-1:-1:-1;;;;;30675:2194:0;;;;:::o;4746:136::-;4804:7;4831:43;4835:1;4838;4831:43;;;;;;;;;;;;;;;;;:3;:43::i;52645:330::-;-1:-1:-1;;;;;52769:16:0;;;52732:4;52769:16;;;:9;:16;;;;;;;;:30;;;;;;;;;;;;52857:23;:37;;;;;;;52732:4;;52769:30;52732:4;;52831:105;;38015:4;;52831:82;;52857:55;;52769:30;52857:41;:55::i;:::-;-1:-1:-1;;;;;52831:21:0;;;;;;:14;:21;;;;;;;:25;:82::i;:105::-;52810:126;52645:330;-1:-1:-1;;;;;52645:330:0:o;28758:1147::-;28852:7;28880:22;;;;28872:63;;;;-1:-1:-1;;;28872:63:0;;;;;;;:::i;:::-;28964:1;28954:7;:11;28946:36;;;;-1:-1:-1;;;28946:36:0;;;;;;;:::i;:::-;29001:28;29023:5;29001:21;:28::i;:::-;28993:63;;;;-1:-1:-1;;;28993:63:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;29075:22:0;;;;;;:15;:22;;;;;24663:2;;29098:5;29075:29;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;29075:29:0;:41;;:48;:75;29067:136;;;;-1:-1:-1;;;29067:136:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;29331:22:0;;;;;;:15;:22;;;;;:48;;29371:7;;29331:22;29354:5;29331:29;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;29331:29:0;:35;;:39;:48::i;:::-;-1:-1:-1;;;;;29293:22:0;;;;;;:15;:22;;;;;;29316:5;29293:29;;;;;;;;;;;;;;;;;;;;;;;;;;;:35;;:86;;;;29390:22;29415:67;29435:46;29458:15;:22;29474:5;29458:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;24791:5;29435:22;;:46;;;;:::i;:::-;29415:15;;:19;:67::i;:::-;-1:-1:-1;;;;;29493:22:0;;;;;;:15;:22;;;;;29390:92;;-1:-1:-1;29516:5:0;29493:29;;;;;;;;;;;;;;;;;;;;;;;;;;;:41;;29540:151;;;;;;;;29574:7;29540:151;;;;29608:17;:24;29626:5;29608:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;29608:24:0;;;;29540:151;;;;;;;;29493:199;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29774:85;;29799:59;;24456:4;;29799:37;;29829:5;29811:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;29799:7;:11;;:37;;;;:::i;:59::-;-1:-1:-1;;;;;29774:20:0;;;;;;:13;:20;;;;;;;:24;:85::i;:::-;-1:-1:-1;;;;;29752:20:0;;;;;;:13;:20;;;;;:107;;;;-1:-1:-1;;28758:1147:0;;;;;:::o;4282:181::-;4340:7;4372:5;;;4396:6;;;;4388:46;;;;-1:-1:-1;;;4388:46:0;;;;;;;:::i;5636:471::-;5694:7;5939:6;5935:47;;-1:-1:-1;5969:1:0;5962:8;;5935:47;6006:5;;;6010:1;6006;:5;:1;6030:5;;;;;:10;6022:56;;;;-1:-1:-1;;;6022:56:0;;;;;;;:::i;6583:132::-;6641:7;6668:39;6672:1;6675;6668:39;;;;;;;;;;;;;;;;;:3;:39::i;49566:448::-;49637:25;;49665:6;49637:34;49618:15;:53;49615:392;;49692:9;49687:191;49711:12;:19;49707:23;;49687:191;;;49822:23;:40;49846:12;49859:1;49846:15;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;49846:15:0;-1:-1:-1;;;;;49822:40:0;-1:-1:-1;;;;;49822:40:0;;;;;;;;;;;;;49756:18;:35;49775:12;49788:1;49775:15;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;49775:15:0;49756:35;;;;;;;;;;;;49793:16;;49817:1;;49775:15;49793:20;49792:26;49756:63;;;;;;;;:106;49732:3;;49687:191;;;-1:-1:-1;49920:15:0;49892:25;:43;49970:16;;49994:1;;49989;49970:20;49969:26;49950:16;:45;49566:448::o;32883:803::-;-1:-1:-1;;;;;33080:20:0;;33029:7;33080:20;;;:13;:20;;;;;;33029:7;33136:5;33131:11;;;;;;;;33115:27;;33286:15;33281:300;33317:8;33328:1;33317:12;33307:7;:22;33281:300;;;33392:1;33360:20;33381:7;33360:29;;;;;;;;;;;;;;:33;33357:213;;;33437:117;33463:90;33478:5;33485:7;33494:8;33534:1;33504:20;33525:7;33504:29;;;;;;;;;;;;;;:31;33537:15;33463:14;:90::i;:::-;33437:21;;:25;:117::i;:::-;33413:141;;33357:213;33331:9;;33281:300;;;-1:-1:-1;;;;;;;33595:20:0;;;;;;:13;:20;;;;;:44;;;33618:21;-1:-1:-1;32883:803:0;;;;;;:::o;5185:192::-;5271:7;5307:12;5299:6;;;;5291:29;;;;-1:-1:-1;;;5291:29:0;;;;;;;;:::i;:::-;-1:-1:-1;;;5343:5:0;;;5185:192::o;7211:278::-;7297:7;7332:12;7325:5;7317:28;;;;-1:-1:-1;;;7317:28:0;;;;;;;;:::i;:::-;;7356:9;7372:1;7368;:5;;;;;;;7211:278;-1:-1:-1;;;;;7211:278:0:o;33694:2646::-;33822:7;;;33953:1;33941:13;;33822:7;34006:8;33991:24;;;;;;;;33965:50;;34041:9;34029:8;:21;34026:812;;;-1:-1:-1;;;;;34201:22:0;;;;;;:15;:22;;;;;;34224:8;34201:32;;;;;;;;;;;;;;;;;;;;;;;;;;;:44;;34246:10;34201:56;;;;;;;;;;;;;;;;;;:63;;;34182:15;:82;34179:648;;-1:-1:-1;;;;;34477:22:0;;;;;;:15;:22;;;;;:84;;34545:15;;34477:22;34500:8;34477:32;;;;;;;;;;;;;;;;;;;;;;;;;;;:44;;34522:10;34477:56;;;;;;;;;;;;;;;;;;;;;:63;;:67;:84::i;:::-;-1:-1:-1;;;;;34411:22:0;;;;;;:15;:22;;;;;;34434:8;34411:32;;;;;;;;;;;;;;;;;;;;;;;;;;;:44;;34456:10;34411:56;;;;;;;;;;;;;;;;;;;;;:150;34601:15;;-1:-1:-1;34679:88:0;34705:61;34601:15;34738:5;34745:8;34755:10;34705:16;:61::i;:::-;34679:21;;:25;:88::i;:::-;34655:112;;34801:10;34786:25;;34179:648;-1:-1:-1;;;;;34925:22:0;;34895:15;34925:22;;;:15;:22;;;;;34997:12;;34925:69;;34997:12;;34895:15;34948:8;34925:32;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;34925:32:0;:44;;:51;;:55;:69::i;:::-;:84;34921:268;;;-1:-1:-1;;;;;35038:22:0;;;;;;:15;:22;;;;;:69;;35094:12;;35038:22;35061:8;35038:32;;;;;;;:69;35025:82;;34921:268;;;-1:-1:-1;35165:12:0;34921:268;35204:9;35199:812;35223:10;35219:1;:14;35199:812;;;35263:12;35259:1;:16;35255:421;;;-1:-1:-1;;;;;35426:22:0;;;;;;:15;:22;;;;;35403:78;;35449:8;35426:32;;;;;;;;;;;;;;;;;;;;;;;;;;;:44;;35471:1;35426:47;;;;;;;;;;;;;;;;;;;;;:54;35403:18;;:22;:78::i;:::-;-1:-1:-1;;;;;35587:22:0;;;;;;:15;:22;;;;;35382:99;;-1:-1:-1;35544:116:0;;35570:89;;35610:8;35587:32;;;;;;;;;;;;;;;;;;;;;;;;;;;:44;;35632:1;35587:47;;;;;;;;;;;;;;;;;;:54;;;35642:5;35648:8;35657:1;35570:16;:89::i;:::-;35544:21;;:25;:116::i;:::-;35520:140;;35255:421;-1:-1:-1;;;;;35698:22:0;;;;;;:15;:22;;;;;35752:12;;35721:8;35698:32;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;35698:32:0;:44;;:51;:66;35694:70;;35690:310;;;-1:-1:-1;;;;;35924:22:0;;;;;;:15;:22;;;;;;35947:8;35924:32;;;;;;;;;;;;;;;;;;;;;;;;;;;:44;;35971:12;35969:1;:14;35924:60;;;;;;;;;;;;;;;;;;35874:15;:22;35890:5;-1:-1:-1;;;;;35874:22:0;-1:-1:-1;;;;;35874:22:0;;;;;;;;;;;;:32;35897:8;35874:32;;;;;;;;;;;;;;;;;;;;;;;;;;;:44;;35919:1;35874:47;;;;;;;;;;;;;;;;:110;;:47;;;;;:110;;;;;;;;;;;;;;;;;;;;35690:310;35235:3;;35199:812;;;;36059:9;36054:120;36078:12;36074:1;:16;36054:120;;;-1:-1:-1;;;;;36112:22:0;;;;;;:15;:22;;;;;;36135:8;36112:32;;;;;;;;;;;;;;;;;;;;;;;;;;;:44;;:50;;;;;;;;;;;;;;;-1:-1:-1;;36112:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;;36092:3;36054:120;;;-1:-1:-1;;;;;;36228:22:0;;;;;;:15;:22;;;;;:62;;36271:18;;36228:22;36251:8;36228:32;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;36228:32:0;:38;;:42;:62::i;:::-;-1:-1:-1;;;;;36187:22:0;;;;;;:15;:22;;;;;;36210:8;36187:32;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;36187:32:0;:103;-1:-1:-1;36309:21:0;;33694:2646;-1:-1:-1;;;;;;;;;33694:2646:0:o;36348:270::-;-1:-1:-1;;;;;36508:22:0;;36465:7;36508:22;;;:15;:22;;;;;36496:97;;24456:4;;36496:75;;36465:7;36531:9;36508:33;;;;;;;;;;;;;;;;;;;;;;;;;;;:45;;36554:4;36508:51;;;;;;;;;;;;;;;;;;:62;;;36496:7;:11;;:75;;;;:::i;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;:::o;5:130::-;72:20;;-1:-1;;;;;44709:54;;45959:35;;45949:2;;46008:1;;45998:12;160:707;;277:3;270:4;262:6;258:17;254:27;244:2;;-1:-1;;285:12;244:2;332:6;319:20;41603:18;;41595:6;41592:30;41589:2;;;-1:-1;;41625:12;41589:2;41670:4;;41662:6;41658:17;41243:2;41237:9;41670:4;41658:17;41273:6;41269:17;;41380:6;41368:10;41365:22;41603:18;41332:10;41329:34;41326:62;41323:2;;;-1:-1;;41391:12;41323:2;41243;41410:22;462:21;;;345:89;-1:-1;519:14;;;;-1:-1;494:17;;;599:27;;;;;596:36;-1:-1;593:2;;;645:1;;635:12;593:2;670:1;661:10;;655:206;680:6;677:1;674:13;655:206;;;1381:20;;748:50;;812:14;;;;702:1;695:9;;;;;840:14;;655:206;;;659:14;;;;;237:630;;;;:::o;1141:166::-;1226:20;;46229:2;46219:13;;46209:2;;46246:1;;46236:12;1592:241;;1696:2;1684:9;1675:7;1671:23;1667:32;1664:2;;;-1:-1;;1702:12;1664:2;1764:53;1809:7;1785:22;1764:53;:::i;1840:366::-;;;1961:2;1949:9;1940:7;1936:23;1932:32;1929:2;;;-1:-1;;1967:12;1929:2;2029:53;2074:7;2050:22;2029:53;:::i;:::-;2019:63;;2137:53;2182:7;2119:2;2162:9;2158:22;2137:53;:::i;:::-;2127:63;;1923:283;;;;;:::o;2213:402::-;;;2352:2;2340:9;2331:7;2327:23;2323:32;2320:2;;;-1:-1;;2358:12;2320:2;72:20;;-1:-1;;;;;44709:54;;45959:35;;45949:2;;-1:-1;;45998:12;45949:2;2410:63;-1:-1;2528:71;2591:7;2510:2;2567:22;;2528:71;:::i;2622:366::-;;;2743:2;2731:9;2722:7;2718:23;2714:32;2711:2;;;-1:-1;;2749:12;2711:2;2811:53;2856:7;2832:22;2811:53;:::i;:::-;2801:63;2901:2;2940:22;;;;1381:20;;-1:-1;;;2705:283::o;2995:527::-;;;;3151:2;3139:9;3130:7;3126:23;3122:32;3119:2;;;-1:-1;;3157:12;3119:2;3219:53;3264:7;3240:22;3219:53;:::i;:::-;3209:63;;3309:2;3352:9;3348:22;1381:20;3317:63;;3435:71;3498:7;3417:2;3478:9;3474:22;3435:71;:::i;:::-;3425:81;;3113:409;;;;;:::o;3529:638::-;;;3700:2;3688:9;3679:7;3675:23;3671:32;3668:2;;;-1:-1;;3706:12;3668:2;3764:17;3751:31;3802:18;;3794:6;3791:30;3788:2;;;-1:-1;;3824:12;3788:2;3854:78;3924:7;3915:6;3904:9;3900:22;3854:78;:::i;:::-;3844:88;;3997:2;3986:9;3982:18;3969:32;3955:46;;3802:18;4013:6;4010:30;4007:2;;;-1:-1;;4043:12;4007:2;;4073:78;4143:7;4134:6;4123:9;4119:22;4073:78;:::i;:::-;4063:88;;;3662:505;;;;;:::o;4174:235::-;;4275:2;4263:9;4254:7;4250:23;4246:32;4243:2;;;-1:-1;;4281:12;4243:2;952:6;939:20;964:30;988:5;964:30;:::i;4416:257::-;;4528:2;4516:9;4507:7;4503:23;4499:32;4496:2;;;-1:-1;;4534:12;4496:2;1087:6;1081:13;1099:30;1123:5;1099:30;:::i;4680:277::-;;4802:2;4790:9;4781:7;4777:23;4773:32;4770:2;;;-1:-1;;4808:12;4770:2;4870:71;4933:7;4909:22;4870:71;:::i;4964:241::-;;5068:2;5056:9;5047:7;5043:23;5039:32;5036:2;;;-1:-1;;5074:12;5036:2;-1:-1;1381:20;;5030:175;-1:-1;5030:175::o;5212:263::-;;5327:2;5315:9;5306:7;5302:23;5298:32;5295:2;;;-1:-1;;5333:12;5295:2;-1:-1;1529:13;;5289:186;-1:-1;5289:186::o;5482:402::-;;;5621:2;5609:9;5600:7;5596:23;5592:32;5589:2;;;-1:-1;;5627:12;5589:2;1394:6;1381:20;5679:63;;5797:71;5860:7;5779:2;5840:9;5836:22;5797:71;:::i;5891:527::-;;;;6047:2;6035:9;6026:7;6022:23;6018:32;6015:2;;;-1:-1;;6053:12;6015:2;1394:6;1381:20;6105:63;;6205:2;6248:9;6244:22;1381:20;6213:63;;6331:71;6394:7;6313:2;6374:9;6370:22;6331:71;:::i;23672:222::-;-1:-1;;;;;44709:54;;;;7289:37;;23799:2;23784:18;;23770:124::o;23901:460::-;-1:-1;;;;;44709:54;;;7158:58;;44709:54;;;;24264:2;24249:18;;7289:37;24347:2;24332:18;;23503:37;;;;24092:2;24077:18;;24063:298::o;24368:349::-;-1:-1;;;;;44709:54;;;;7158:58;;24703:2;24688:18;;23503:37;24531:2;24516:18;;24502:215::o;25064:370::-;25241:2;25255:47;;;42463:12;;25226:18;;;43667:19;;;25064:370;;25241:2;41870:14;;;;43707;;;;25064:370;7897:260;7922:6;7919:1;7916:13;7897:260;;;7983:13;;-1:-1;;;;;44709:54;7289:37;;43152:14;;;;6579;;;;44720:42;7937:9;7897:260;;;-1:-1;25308:116;;25212:222;-1:-1;;;;;;25212:222::o;25441:478::-;25672:2;25686:47;;;42463:12;;25657:18;;;43667:19;;;25441:478;;25672:2;43707:14;;;;;;41870;;;25441:478;8813:341;8838:6;8835:1;8832:13;8813:341;;;8899:13;;22996:23;;23503:37;;23162:16;;;23156:23;23233:14;;;23503:37;23328:16;;23322:23;23399:14;;;23503:37;6878:4;6869:14;;;;43152;;;;8860:1;8853:9;8813:341;;;-1:-1;25739:170;;25643:276;-1:-1;;;;;;;25643:276::o;25926:315::-;26099:3;26084:19;;26088:9;9580:21;25926:315;9607:258;42769:4;9629:1;9626:13;9607:258;;;9693:13;;23503:37;;7060:4;7051:14;;;;43152;;;;9654:1;9647:9;9607:258;;;9611:14;;;26070:171;;;;:::o;26248:370::-;26425:2;26439:47;;;42463:12;;26410:18;;;43667:19;;;26248:370;;26425:2;41870:14;;;;43707;;;;26248:370;10324:260;10349:6;10346:1;10343:13;10324:260;;;10410:13;;23503:37;;43152:14;;;;7051;;;;10371:1;10364:9;10324:260;;26625:210;44621:13;;44614:21;10679:34;;26746:2;26731:18;;26717:118::o;27099:310::-;;27246:2;;27267:17;27260:47;11031:5;42463:12;43679:6;27246:2;27235:9;27231:18;43667:19;-1:-1;45591:101;45605:6;45602:1;45599:13;45591:101;;;45672:11;;;;;45666:18;45653:11;;;43707:14;45653:11;45646:39;45620:10;;45591:101;;;45707:6;45704:1;45701:13;45698:2;;;-1:-1;43707:14;45763:6;27235:9;45754:16;;45747:27;45698:2;-1:-1;45879:7;45863:14;-1:-1;;45859:28;11189:39;;;;43707:14;11189:39;;27217:192;-1:-1;;;27217:192::o;27416:416::-;27616:2;27630:47;;;11465:2;27601:18;;;43667:19;11501:34;43707:14;;;11481:55;-1:-1;;;11556:12;;;11549:30;11598:12;;;27587:245::o;27839:416::-;28039:2;28053:47;;;11849:2;28024:18;;;43667:19;-1:-1;;;43707:14;;;11865:36;11920:12;;;28010:245::o;28262:416::-;28462:2;28476:47;;;12171:2;28447:18;;;43667:19;12207:34;43707:14;;;12187:55;-1:-1;;;12262:12;;;12255:38;12312:12;;;28433:245::o;28685:416::-;28885:2;28899:47;;;12563:2;28870:18;;;43667:19;12599:34;43707:14;;;12579:55;-1:-1;;;12654:12;;;12647:36;12702:12;;;28856:245::o;29108:416::-;29308:2;29322:47;;;12953:2;29293:18;;;43667:19;-1:-1;;;43707:14;;;12969:37;13025:12;;;29279:245::o;29531:416::-;29731:2;29745:47;;;13276:2;29716:18;;;43667:19;13312:29;43707:14;;;13292:50;13361:12;;;29702:245::o;29954:416::-;30154:2;30168:47;;;13612:2;30139:18;;;43667:19;-1:-1;;;43707:14;;;13628:42;13689:12;;;30125:245::o;30377:416::-;30577:2;30591:47;;;13940:2;30562:18;;;43667:19;13976:31;43707:14;;;13956:52;14027:12;;;30548:245::o;30800:416::-;31000:2;31014:47;;;14278:2;30985:18;;;43667:19;-1:-1;;;43707:14;;;14294:45;14358:12;;;30971:245::o;31223:416::-;31423:2;31437:47;;;14609:2;31408:18;;;43667:19;14645:30;43707:14;;;14625:51;14695:12;;;31394:245::o;31646:416::-;31846:2;31860:47;;;14946:2;31831:18;;;43667:19;14982:34;43707:14;;;14962:55;-1:-1;;;15037:12;;;15030:30;15079:12;;;31817:245::o;32069:416::-;32269:2;32283:47;;;15330:2;32254:18;;;43667:19;15366:29;43707:14;;;15346:50;15415:12;;;32240:245::o;32492:416::-;32692:2;32706:47;;;15666:2;32677:18;;;43667:19;15702:33;43707:14;;;15682:54;15755:12;;;32663:245::o;32915:416::-;33115:2;33129:47;;;16006:2;33100:18;;;43667:19;16042:32;43707:14;;;16022:53;16094:12;;;33086:245::o;33338:416::-;33538:2;33552:47;;;16345:2;33523:18;;;43667:19;-1:-1;;;43707:14;;;16361:44;16424:12;;;33509:245::o;33761:416::-;33961:2;33975:47;;;16675:2;33946:18;;;43667:19;16711:34;43707:14;;;16691:55;-1:-1;;;16766:12;;;16759:40;16818:12;;;33932:245::o;34184:416::-;34384:2;34398:47;;;17069:2;34369:18;;;43667:19;17105:34;43707:14;;;17085:55;17174:25;17160:12;;;17153:47;17219:12;;;34355:245::o;34607:416::-;34807:2;34821:47;;;34792:18;;;43667:19;17506:34;43707:14;;;17486:55;17560:12;;;34778:245::o;35030:416::-;35230:2;35244:47;;;17811:2;35215:18;;;43667:19;17847:34;43707:14;;;17827:55;-1:-1;;;17902:12;;;17895:30;17944:12;;;35201:245::o;35453:416::-;35653:2;35667:47;;;18195:2;35638:18;;;43667:19;18231:34;43707:14;;;18211:55;-1:-1;;;18286:12;;;18279:25;18323:12;;;35624:245::o;35876:416::-;36076:2;36090:47;;;18574:2;36061:18;;;43667:19;18610:34;43707:14;;;18590:55;-1:-1;;;18665:12;;;18658:38;18715:12;;;36047:245::o;36299:416::-;36499:2;36513:47;;;18966:2;36484:18;;;43667:19;-1:-1;;;43707:14;;;18982:37;19038:12;;;36470:245::o;36722:416::-;36922:2;36936:47;;;19289:2;36907:18;;;43667:19;-1:-1;;;43707:14;;;19305:43;19367:12;;;36893:245::o;37145:416::-;37345:2;37359:47;;;19618:2;37330:18;;;43667:19;19654:34;43707:14;;;19634:55;-1:-1;;;19709:12;;;19702:31;19752:12;;;37316:245::o;37568:416::-;37768:2;37782:47;;;20003:2;37753:18;;;43667:19;20039:28;43707:14;;;20019:49;20087:12;;;37739:245::o;37991:416::-;38191:2;38205:47;;;20338:2;38176:18;;;43667:19;20374:32;43707:14;;;20354:53;20426:12;;;38162:245::o;38414:416::-;38614:2;38628:47;;;38599:18;;;43667:19;20713:34;43707:14;;;20693:55;20767:12;;;38585:245::o;38837:416::-;39037:2;39051:47;;;21018:2;39022:18;;;43667:19;21054:34;43707:14;;;21034:55;-1:-1;;;21109:12;;;21102:40;21161:12;;;39008:245::o;39260:416::-;39460:2;39474:47;;;21412:2;39445:18;;;43667:19;21448:34;43707:14;;;21428:55;21517:28;21503:12;;;21496:50;21565:12;;;39431:245::o;39683:416::-;39883:2;39897:47;;;21816:2;39868:18;;;43667:19;21852:34;43707:14;;;21832:55;-1:-1;;;21907:12;;;21900:37;21956:12;;;39854:245::o;40106:416::-;40306:2;40320:47;;;22207:2;40291:18;;;43667:19;22243:33;43707:14;;;22223:54;22296:12;;;40277:245::o;40529:416::-;40729:2;40743:47;;;22547:2;40714:18;;;43667:19;22583:34;43707:14;;;22563:55;-1:-1;;;22638:12;;;22631:38;22688:12;;;40700:245::o;40952:222::-;23503:37;;;41079:2;41064:18;;41050:124::o;46024:111::-;46105:5;44621:13;44614:21;46083:5;46080:32;46070:2;;46126:1;;46116:12
Swarm Source
ipfs://71f9d7de36bb6be53dc576498f0cdba64e39e59f2f31b3d93ba12cb1af148cc4
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.