More Info
Private Name Tags
ContractCreator
Latest 14 from a total of 14 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Transfer | 616416 | 2 days ago | IN | 0.1 S | 0.0000231 | ||||
Set Lockup Days | 517935 | 3 days ago | IN | 0 S | 0.0033605 | ||||
Set Cool Down Da... | 517927 | 3 days ago | IN | 0 S | 0.00283096 | ||||
Set Cool Down Da... | 517592 | 3 days ago | IN | 0 S | 0.00524128 | ||||
Stake Tier FS To... | 314232 | 9 days ago | IN | 0 S | 0.00029317 | ||||
Set Tier FS Toke... | 241107 | 11 days ago | IN | 0 S | 0.00035092 | ||||
Set Tier FS Toke... | 241104 | 11 days ago | IN | 0 S | 0.00034459 | ||||
Set Tier FS Toke... | 241102 | 11 days ago | IN | 0 S | 0.00033823 | ||||
Set Tier FS Toke... | 241099 | 11 days ago | IN | 0 S | 0.000332 | ||||
Set Tier FS Toke... | 241097 | 11 days ago | IN | 0 S | 0.00032567 | ||||
Set Tier FS Toke... | 241095 | 11 days ago | IN | 0 S | 0.00031931 | ||||
Set Tier FS Toke... | 241093 | 11 days ago | IN | 0 S | 0.00031295 | ||||
Set Tier FS Toke... | 241091 | 11 days ago | IN | 0 S | 0.00030663 | ||||
Set Tier FS Toke... | 241089 | 11 days ago | IN | 0 S | 0.00034305 |
Loading...
Loading
Contract Name:
StakerTierFSonic
Compiler Version
v0.8.18+commit.87f61d96
Contract Source Code (Solidity)
/** *Submitted for verification at SonicScan.org on 2024-12-16 */ // SPDX-License-Identifier: MIT pragma solidity ^0.8.10; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // CAUTION // This version of SafeMath should only be used with Solidity 0.8 or later, // because it relies on the compiler's built in overflow checks. /** * @dev Wrappers over Solidity's arithmetic operations. * * NOTE: `SafeMath` is no longer needed starting with Solidity 0.8. The compiler * now has built in overflow checking. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd( uint256 a, uint256 b ) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub( uint256 a, uint256 b ) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul( uint256 a, uint256 b ) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv( uint256 a, uint256 b ) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod( uint256 a, uint256 b ) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { return a + b; } /** * @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 a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { return a * b; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b <= a, errorMessage); return a - b; } } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * 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) { unchecked { require(b > 0, errorMessage); return a / b; } } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a % b; } } } /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface( bytes4 interfaceId ) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } } /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString( uint256 value, uint256 length ) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } } /** * @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; 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" ); (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"); (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"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data ) internal returns (bytes memory) { return functionDelegateCall( target, data, "Address: low-level delegate call failed" ); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal 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 assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { function hasRole( bytes32 role, address account ) external view returns (bool); function getRoleAdmin(bytes32 role) external view returns (bytes32); function grantRole(bytes32 role, address account) external; function revokeRole(bytes32 role, address account) external; function renounceRole(bytes32 role, address account) external; } /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged( bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole ); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {_setupRole}. */ event RoleGranted( bytes32 indexed role, address indexed account, address indexed sender ); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked( bytes32 indexed role, address indexed account, address indexed sender ); /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role, _msgSender()); _; } modifier isAdmin() { require( hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), "Account is not in the admin list" ); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface( bytes4 interfaceId ) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole( bytes32 role, address account ) public view override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", Strings.toHexString(uint160(account), 20), " is missing role ", Strings.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole( bytes32 role, address account ) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole( bytes32 role, address account ) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole( bytes32 role, address account ) public virtual override { require( account == _msgSender(), "AccessControl: can only renounce roles for self" ); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } function _grantRole(bytes32 role, address account) private { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } function _revokeRole(bytes32 role, address account) private { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } } /** * @dev Required interface of an ERC1155 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-1155[EIP]. * * _Available since v3.1._ */ interface IERC1155 is IERC165 { /** * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. */ event TransferSingle( address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value ); /** * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all * transfers. */ event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll( address indexed account, address indexed operator, bool approved ); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns the amount of tokens of token type `id` owned by `account`. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf( address account, uint256 id ) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch( address[] calldata accounts, uint256[] calldata ids ) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the caller. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll( address account, address operator ) external view returns (bool); /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes calldata data ) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external; function mint(uint256 id, address receiver) external; } /** * @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); function mintToken(address account, uint256 amount) external; /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval( address indexed owner, address indexed spender, uint256 value ); /** * @dev Destroys `amount` tokens from the caller. * * See {ERC20-_burn}. */ function burn(uint256 amount) external; /** * @dev Destroys `amount` tokens from `account`, deducting from the caller's * allowance. * * See {ERC20-_burn} and {ERC20-allowance}. * * Requirements: * * - the caller must have allowance for ``accounts``'s tokens of at least * `amount`. */ function burnFrom(address account, uint256 amount) external; } /** * @dev _Available since v3.1._ */ interface IERC1155Receiver is IERC165 { /** @dev Handles the receipt of a single ERC1155 token type. This function is called at the end of a `safeTransferFrom` after the balance has been updated. To accept the transfer, this must return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` (i.e. 0xf23a6e61, or its own function selector). @param operator The address which initiated the transfer (i.e. msg.sender) @param from The address which previously owned the token @param id The ID of the token being transferred @param value The amount of tokens being transferred @param data Additional data with no specified format @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed */ function onERC1155Received( address operator, address from, uint256 id, uint256 value, bytes calldata data ) external returns (bytes4); /** @dev Handles the receipt of a multiple ERC1155 token types. This function is called at the end of a `safeBatchTransferFrom` after the balances have been updated. To accept the transfer(s), this must return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` (i.e. 0xbc197c81, or its own function selector). @param operator The address which initiated the batch transfer (i.e. msg.sender) @param from The address which previously owned the token @param ids An array containing ids of each token being transferred (order and length must match values array) @param values An array containing amounts of each token being transferred (order and length must match ids array) @param data Additional data with no specified format @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed */ function onERC1155BatchReceived( address operator, address from, uint256[] calldata ids, uint256[] calldata values, bytes calldata data ) external returns (bytes4); } /** * @dev _Available since v3.1._ */ abstract contract ERC1155Receiver is ERC165, IERC1155Receiver { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface( bytes4 interfaceId ) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId); } } /** * @dev _Available since v3.1._ */ contract ERC1155Holder is ERC1155Receiver { function onERC1155Received( address, address, uint256, uint256, bytes memory ) public virtual override returns (bytes4) { return this.onERC1155Received.selector; } function onERC1155BatchReceived( address, address, uint256[] memory, uint256[] memory, bytes memory ) public virtual override returns (bytes4) { return this.onERC1155BatchReceived.selector; } } /** * @dev * Interface to access the TierFactory FSonic **/ interface ITierFactoryFSonic { /** * @dev * Returns the balance of the number of NFTs based on the NFTId **/ function balanceOf( address _owner, uint256 _id ) external view returns (uint256); /** * @dev * Returns the balance of a list of addresses **/ function balanceOfBatch( address[] calldata _owners, uint256[] calldata _ids ) external view returns (uint256[] memory); /** * @dev * Mint the NFT **/ function mint( address _to, uint256 _id, uint256 _quantity, bytes calldata _data ) external; /** * @dev * Check if the NFT is mintable **/ function isMintable(uint256 _id) external returns (bool); /** * @dev * Transfer the NFT _from _to **/ function safeTransferFrom( address _from, address _to, uint256 _id, uint256 _amount, bytes calldata _data ) external; /** * @dev * Safe transfer a batch of NFTs _from _to **/ function safeBatchTransferFrom( address _from, address _to, uint256[] calldata _ids, uint256[] calldata _amounts, bytes calldata _data ) external; /** * @dev * Get max supply for token id **/ function maxSupply(uint256 _id) external view returns (uint256); /** * @dev * Get the Tier based on the NFT Id **/ function getTierByNFTId(uint256 _nftId) external view returns (uint256); } /** * @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 Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn( token, abi.encodeWithSelector(token.transfer.selector, to, value) ); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn( token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value) ); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn( token, abi.encodeWithSelector( token.approve.selector, spender, newAllowance ) ); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require( oldAllowance >= value, "SafeERC20: decreased allowance below zero" ); uint256 newAllowance = oldAllowance - value; _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 require( abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed" ); } } } /** * @dev Staking Tier FSonic contract. * Staking NFT: * Every wallet can stake only one NFT at a time. * Staking FS Tokens: * Every wallet can stake only x tokens * * Staking only per wallet at a time, either for NFT or FS Tokens **/ contract StakerTierFSonic is ERC1155Holder, AccessControl { using SafeMath for uint256; using SafeERC20 for IERC20; ITierFactoryFSonic public tierFactory; IERC20 public fsToken; IERC20 public sFSToken; // The period of lockup days before you can unstake NFT or FS tokens. uint256 public lockupDays = 7; // Cooldown days used after staking to calculate lockup period uint256 public coolDownDays = 0; // When unstaking FS tokens before lockup period, we keep 10% as a penalty uint256 public withholdUnstakingPercentage = 10; // The dev wallet address that penalty FS tokens are sent to address private devWallet; // Struct for the staked NFT struct StakedTierNFT { bool currentlyStaked; uint256 nftId; uint256 tierId; uint256 creationTimestamp; // EPOCH timestamp uint256 stakingLockupDays; uint256 cancelStackingCoolDownDays; } // Tier for FS Tokens in staked contract within a certain range struct TierFSTokens { bool initialized; uint256 tierId; uint256 minFSTokens; uint256 maxFSTokens; } // Struct for the staked FS tokens struct StakedTierFSToken { bool currentlyStaked; uint256 tokenAmount; uint256 tierId; uint256 withholdUnstakingPercentage; uint256 creationTimestamp; // EPOCH timestamp uint256 stakingLockupDays; uint256 cancelStackingCoolDownDays; } // Contains the list of Tiers based on the FS Tokens min max range TierFSTokens[] public tierFSTokensList; // Each wallet can only stake either NFT or FS token and also only once. mapping(address => StakedTierNFT) public walletStakedTierNFTMapping; mapping(address => StakedTierFSToken) public walletStakedTierFSTokenMapping; // Events event AddToStakedTierNFT(address staker, uint256 nftId); event AddToStakedTierFSToken(address staker, uint256 fsTokensStaked); event RemovedFromStakedTierNFT(address staker, uint256 nftId); event RemovedFromStakedTierFSToken(address staker, uint256 fsTokensStaked); event UnstakedBeforeLockupPeriodFSToken( address staker, uint256 fsTokensStakedReturned, uint256 withheldFSTokens ); // Loggers for admin only event ChangedTierFactoryAddress( address admin, ITierFactoryFSonic oldTierFactoryAddress, ITierFactoryFSonic newTierFactoryAddress ); event ChangedLockupDays( address admin, uint256 oldLockupFactoryDays, uint256 newLockupFactoryDays ); event ChangedCoolDownDays( address admin, uint256 oldCoolDownDays, uint256 newCoolDownDays ); event ChangedDevWalletAddress( address admin, address oldDevWalletAddress, address newDevWalletAddress ); event ChangedWithholdUnstakingPercentage( address admin, uint256 oldUnstakingPercentage, uint256 newUnstakingPercentage ); event UpdateOrCreateFSTierTokenRange( address admin, uint256 tierId, uint256 minFSTokens, uint256 maxFSTokens ); constructor( ITierFactoryFSonic _tierFactory, IERC20 _fsToken, IERC20 _sFSToken, address _devWallet ) { _setupRole(DEFAULT_ADMIN_ROLE, msg.sender); // Add contract publisher to the admin users tierFactory = _tierFactory; fsToken = _fsToken; sFSToken = _sFSToken; devWallet = _devWallet; } // Needed for compiling function supportsInterface( bytes4 _interfaceId ) public view virtual override(ERC1155Receiver, AccessControl) returns (bool) { return super.supportsInterface(_interfaceId); } // Getters and Setters /** * @dev * Update or create a Tier FS token range **/ function setTierFSTokenRange( uint256 _tierId, uint256 _minFSTokens, uint256 _maxFSTokens ) public isAdmin { // First check if the tier already exists and if so, update the current tier. bool _tierExists = false; uint256 _tierIndex = 0; for (uint256 i = 0; i < tierFSTokensList.length; i++) { if (tierFSTokensList[i].tierId == _tierId) { _tierIndex = i; _tierExists = true; break; } } if (_tierExists) { // The tier already exists, update the existing Tier tierFSTokensList[_tierIndex].minFSTokens = _minFSTokens; tierFSTokensList[_tierIndex].maxFSTokens = _maxFSTokens; } else { // The tier does not exist, create a new entry tierFSTokensList.push( TierFSTokens(true, _tierId, _minFSTokens, _maxFSTokens) ); } emit UpdateOrCreateFSTierTokenRange( msg.sender, _tierId, _minFSTokens, _maxFSTokens ); } /** * @dev * Returns back the entire list of FS Tier tokens **/ function getTierFSTokens() public view returns (TierFSTokens[] memory tierFSTokens) { return tierFSTokensList; } /** * @dev Replace the existing TierFactory address with a new one, only admins. **/ function setTierFactoryAddress( ITierFactoryFSonic _tierFactory ) public isAdmin { ITierFactoryFSonic _oldTierFactoryAddress = tierFactory; tierFactory = _tierFactory; emit ChangedTierFactoryAddress( msg.sender, _oldTierFactoryAddress, _tierFactory ); } /** * @dev Replace the lockup_days period, only admins. **/ function setLockupDays(uint256 _days) public isAdmin { uint256 _oldLockupDays = lockupDays; lockupDays = _days; emit ChangedLockupDays(msg.sender, _oldLockupDays, _days); } /** * @dev Replace the cooldowndays period, only admins. **/ function setCoolDownDays(uint256 _days) public isAdmin { uint256 _oldCoolDownDays = coolDownDays; coolDownDays = _days; emit ChangedCoolDownDays(msg.sender, _oldCoolDownDays, _days); } /** * @dev Replace the dev wallet **/ function setDevWalletAddress(address _devWallet) public isAdmin { address _oldDevWallet = devWallet; devWallet = _devWallet; emit ChangedDevWalletAddress(msg.sender, _oldDevWallet, _devWallet); } /** * @dev Replace the withhold unstaking percentage **/ function setWithholdUnstakingPercentage( uint256 _withholdUnstakingPercentage ) public isAdmin { require( _withholdUnstakingPercentage < 100, "You cannot withhold more than 99 percent" ); require( _withholdUnstakingPercentage >= 1, "You need to withhold at least 1 percent" ); uint256 _oldWithholdUnstakingPercentage = withholdUnstakingPercentage; withholdUnstakingPercentage = _withholdUnstakingPercentage; emit ChangedWithholdUnstakingPercentage( msg.sender, _oldWithholdUnstakingPercentage, _withholdUnstakingPercentage ); } /** * @dev * Returns the NFT ID currently staked **/ function getNFTIdStaked( address _wallet ) public view returns (uint256 nftIdStaked) { require( hasWalletCurrentlyStakedNFT(_wallet) == true, "Wallet has currently no NFT staked" ); require( hasWalletCurrentlyStakedFSTokens(_wallet) == false, "Wallet has staked FS Tokens and not NFTs" ); return walletStakedTierNFTMapping[_wallet].nftId; } /** * @dev * Returns the token amount staked **/ function getTokensAmountStaked( address _wallet ) public view returns (uint256 tokenAmountStaked) { require( hasWalletCurrentlyStakedNFT(_wallet) == false, "Wallet has staked NFTs and not FS tokens" ); require( hasWalletCurrentlyStakedFSTokens(_wallet) == true, "Wallet has currently no FS Tokens staked" ); return walletStakedTierFSTokenMapping[_wallet].tokenAmount; } /** * @dev * Returns back the Tier for staked benefits, either the token staked or NFT staked **/ function getTierBenefitForStaker( address _wallet ) public view returns (uint256 tierId) { uint256 result = 0; if (hasWalletCurrentlyStakedNFT(_wallet)) { // If the wallet has staked NFT, get back the Tier for that NFT and return it. result = tierFactory.getTierByNFTId(getNFTIdStaked(_wallet)); } else if (hasWalletCurrentlyStakedFSTokens(_wallet)) { // If the wallet has staked FS tokens, calculate the TierID for the tokens staked uint256 _fsTokenAmountToStake = walletStakedTierFSTokenMapping[ _wallet ].tokenAmount; result = getTierIdFromTokensStaked(_fsTokenAmountToStake); } return result; } /** * @dev * Returns back the Tier for the Tokens staked **/ function getTierIdFromTokensStaked( uint256 _tokensStaked ) public view returns (uint256 tierId) { uint256 result = 0; for (uint256 i = 0; i < tierFSTokensList.length; i++) { if ( _tokensStaked >= tierFSTokensList[i].minFSTokens && _tokensStaked <= tierFSTokensList[i].maxFSTokens ) { result = tierFSTokensList[i].tierId; break; } } return result; } /** * @dev Returns uint256 lockupTime left for staked address for NFT Staked **/ function getLockupTimeLeftStakedNFT( address _wallet ) public view returns (uint256 lockupTimeLeft) { require( hasWalletCurrentlyStakedNFT(_wallet) == true, "Wallet has currently no NFT staked" ); require( hasWalletCurrentlyStakedFSTokens(_wallet) == false, "Wallet has staked FS Tokens and not NFTs" ); StakedTierNFT memory _stakedTierNFT = walletStakedTierNFTMapping[ _wallet ]; uint256 result = 0; if ( (_stakedTierNFT.creationTimestamp + (_stakedTierNFT.stakingLockupDays * 1 days) - block.timestamp) > 0 ) { result = _stakedTierNFT.creationTimestamp + (_stakedTierNFT.stakingLockupDays * 1 days) - block.timestamp; } return result; } /** * @dev Returns uint256 lockupTime left for staked address for Tokens Stakend **/ function getLockupTimeLeftStakedFSTokens( address _wallet ) public view returns (uint256 lockupTimeLeft) { require( hasWalletCurrentlyStakedNFT(_wallet) == false, "Wallet has staked NFTs and not FS tokens" ); require( hasWalletCurrentlyStakedFSTokens(_wallet) == true, "Wallet has currently no FS Tokens staked" ); StakedTierFSToken memory _stakedTierFSToken = walletStakedTierFSTokenMapping[_wallet]; uint256 result = 0; if ( (_stakedTierFSToken.creationTimestamp + (_stakedTierFSToken.stakingLockupDays * 1 days) - block.timestamp) > 0 ) { result = _stakedTierFSToken.creationTimestamp + (_stakedTierFSToken.stakingLockupDays * 1 days) - block.timestamp; } return result; } // Checks /** * @dev Check if account has any Completed staked NFTs for Tier **/ function hasWalletCompletedStakingNFT( address _wallet ) public view returns (bool hasCompletedStakingNFT) { bool result = true; // 1. get the staked NFT object StakedTierNFT memory _stakedTierNFT = walletStakedTierNFTMapping[ _wallet ]; // 2. Check if the lockup period is still counting // If the creationTimestamp with added lockupDays is equal or bigger than now, then the auction has expired if ( _stakedTierNFT.creationTimestamp + _stakedTierNFT.stakingLockupDays * 1 days >= block.timestamp ) { result = false; } return result; } /** * @dev Check if account has any Completed staked FS Tokens for Tier **/ function hasWalletCompletedStakingFSTokens( address _wallet ) public view returns (bool hasCompletedStakingFSTokens) { bool result = true; // 1. get the staked NFT object StakedTierFSToken memory _stakedTierFSToken = walletStakedTierFSTokenMapping[_wallet]; // 2. Check if the lockup period is still counting // If the creationTimestamp with added lockupDays is equal or bigger than now, then the auction has expired if ( _stakedTierFSToken.creationTimestamp + _stakedTierFSToken.stakingLockupDays * 1 days >= block.timestamp ) { result = false; } return result; } /** * @dev Check if address has already staked for another NFT Tier **/ function hasWalletCurrentlyStakedNFT( address _wallet ) public view returns (bool hasStakedNFT) { bool result = false; if (walletStakedTierNFTMapping[_wallet].currentlyStaked == true) { result = true; } return result; } /** * @dev Check if address has already staked for Tokens **/ function hasWalletCurrentlyStakedFSTokens( address _wallet ) public view returns (bool hasStakedFSTokens) { bool result = false; if (walletStakedTierFSTokenMapping[_wallet].currentlyStaked == true) { result = true; } return result; } /** * @dev Returns true if address can cancel staked NFT **/ function hasCancelCoolDownDaysExpiredForStakedNFT( address _wallet ) public view returns (bool expired) { require( hasWalletCurrentlyStakedNFT(_wallet) == true, "You have currently no NFT staked" ); require( hasWalletCompletedStakingNFT(_wallet) == true, "Lockup period still pending" ); bool result = true; // 1. get the staked NFT object StakedTierNFT memory _stakedTierNFT = walletStakedTierNFTMapping[ _wallet ]; // 2. Check if the cool down period has expired // If the creationTimestamp with added lockupDays is equal or bigger than now, then the auction has expired if ( _stakedTierNFT.creationTimestamp + (_stakedTierNFT.stakingLockupDays * 1 days) + (_stakedTierNFT.cancelStackingCoolDownDays * 1 days) >= block.timestamp ) { result = false; } return result; } // BusinessLogic /** * @dev Transfers the NFT of the msg.sender to this contract to be staked * You can only stake once per wallet */ function stakeTierNFT(uint256 _nftId) public { require( tierFactory.balanceOf(msg.sender, _nftId) > 0, "You do not own this NFT" ); require( hasWalletCurrentlyStakedNFT(msg.sender) == false, "You have already staked NFTs" ); require( hasWalletCurrentlyStakedFSTokens(msg.sender) == false, "You have already staked FSTokens" ); // SafeTransfer the NFT from the msg.sender to the contract tierFactory.safeTransferFrom(msg.sender, address(this), _nftId, 1, ""); // Create a new staking NFT object and add them to the mapping uint256 _tierId = tierFactory.getTierByNFTId(_nftId); walletStakedTierNFTMapping[msg.sender] = StakedTierNFT( true, _nftId, _tierId, block.timestamp, lockupDays, coolDownDays ); // Emit event emit AddToStakedTierNFT(msg.sender, _nftId); } /** * @dev Transfers the FSTokens of the msg.sender to this contract to be staked. * Wallet can only stake once per wallet **/ function stakeTierFSTokens(uint256 _fsTokenAmountToStake) public { require( fsToken.balanceOf(msg.sender) >= _fsTokenAmountToStake, "You do not own enough tokens to stake" ); require( hasWalletCurrentlyStakedNFT(msg.sender) == false, "You have already staked NFTs" ); require( hasWalletCurrentlyStakedFSTokens(msg.sender) == false, "You have already staked FSTokens" ); // SafeTransfer the tokens from msg.sender to this contract fsToken.safeTransferFrom( msg.sender, address(this), _fsTokenAmountToStake ); // Mint sFS tokens sFSToken.mintToken(msg.sender, _fsTokenAmountToStake); // Get the Tier Id from the amount of _fsTokenAmountToStake uint256 _tierId = getTierIdFromTokensStaked(_fsTokenAmountToStake); // Create a new staking FSToken object and add them to the mapping walletStakedTierFSTokenMapping[msg.sender] = StakedTierFSToken( true, _fsTokenAmountToStake, _tierId, withholdUnstakingPercentage, block.timestamp, lockupDays, coolDownDays ); // Emit event emit AddToStakedTierFSToken(msg.sender, _fsTokenAmountToStake); } /** * @dev Add more tokens to Staked FS Tokens **/ function updateCurrentStakedFSTokens(uint256 _fsTokenAmountToStake) public { require( fsToken.balanceOf(msg.sender) >= _fsTokenAmountToStake, "You do not own enough tokens to stake" ); require( hasWalletCurrentlyStakedNFT(msg.sender) == false, "You have already staked NFTs" ); require( hasWalletCurrentlyStakedFSTokens(msg.sender) == true, "You do not have staked FSTokens" ); // SafeTransfer the tokens from msg.sender to this contract fsToken.safeTransferFrom( msg.sender, address(this), _fsTokenAmountToStake ); // Mint sFS tokens sFSToken.mintToken(msg.sender, _fsTokenAmountToStake); // Create a new staking FSToken object and add them to the mapping walletStakedTierFSTokenMapping[msg.sender].tokenAmount = walletStakedTierFSTokenMapping[msg.sender].tokenAmount + _fsTokenAmountToStake; // Update the Tier id uint256 _tierId = getTierIdFromTokensStaked( walletStakedTierFSTokenMapping[msg.sender].tokenAmount ); walletStakedTierFSTokenMapping[msg.sender].tierId = _tierId; // Reset the lockup period in days walletStakedTierFSTokenMapping[msg.sender].creationTimestamp = block .timestamp; // Emit event emit AddToStakedTierFSToken(msg.sender, _fsTokenAmountToStake); } /** * @dev Cancels the staked NFT and returns it to the owner */ function unstakeTierNFT() public { require( hasWalletCurrentlyStakedNFT(msg.sender) == true, "You have currently no NFT staked" ); require( hasWalletCompletedStakingNFT(msg.sender) == true, "Lockup period still pending" ); require( hasCancelCoolDownDaysExpiredForStakedNFT(msg.sender) == true, "You need to wait for the cool down period to expire" ); // 1. get the staked NFT object StakedTierNFT memory _stakedTierNFT = walletStakedTierNFTMapping[ msg.sender ]; // 2. Since the staking lockup period has expired, transfer the NFT back to the owner // SafeTransfer the NFT from the msg.sender to the contract tierFactory.safeTransferFrom( address(this), msg.sender, _stakedTierNFT.nftId, 1, "" ); // 3. Remove the StakedTierNFT Object from the mapping delete walletStakedTierNFTMapping[msg.sender]; // Emit event emit RemovedFromStakedTierNFT(msg.sender, _stakedTierNFT.nftId); } /** * @dev Unstake FS Tokens after lockup period */ function unstakeTierFSTokensAfterLockupPeriod() public { require( hasWalletCurrentlyStakedFSTokens(msg.sender) == true, "You have no FSTokens staked" ); require( hasWalletCompletedStakingFSTokens(msg.sender) == true, "Lockup period still pending" ); // 1. get the staked NFT object StakedTierFSToken memory _stakedTierFSToken = walletStakedTierFSTokenMapping[ msg.sender ]; require( sFSToken.balanceOf(msg.sender) >= _stakedTierFSToken.tokenAmount, "You don't have enough sFS token!" ); // 2. Since the staking lockup period has expired, transfer the FS Tokens back to the owner // SafeTransfer the FSTokens from the contract to the msg.sender fsToken.safeTransfer(msg.sender, _stakedTierFSToken.tokenAmount); // burn sFS tokens of user sFSToken.burnFrom(msg.sender, _stakedTierFSToken.tokenAmount); // 3. Remove the StakedTierFSToken Object from the mapping delete walletStakedTierFSTokenMapping[msg.sender]; // Emit event emit RemovedFromStakedTierFSToken( msg.sender, _stakedTierFSToken.tokenAmount ); } /** * @dev Unstake FS Token while lockup period still pending **/ function unstakeTierFSTokensBeforeLockupPeriod() public { require( hasWalletCurrentlyStakedFSTokens(msg.sender) == true, "You have no FSTokens staked" ); require( hasWalletCompletedStakingFSTokens(msg.sender) == false, "Lockup period has expired" ); // 1. get the staked NFT object StakedTierFSToken memory _stakedTierFSToken = walletStakedTierFSTokenMapping[ msg.sender ]; require( sFSToken.balanceOf(msg.sender) >= _stakedTierFSToken.tokenAmount, "You don't have enough sFS token!" ); uint256 _fsTokensToReturnToStaker = 0; uint256 _fsTokensPenaltyToDevWallet = 0; // 2. Set the tokens that need to be returned _fsTokensPenaltyToDevWallet = (_stakedTierFSToken.tokenAmount * _stakedTierFSToken.withholdUnstakingPercentage) / 100; _fsTokensToReturnToStaker = _stakedTierFSToken.tokenAmount - _fsTokensPenaltyToDevWallet; // 3. Safe transfer the tokens to the dev wallet and the staker fsToken.safeTransfer(msg.sender, _fsTokensToReturnToStaker); fsToken.safeTransfer(devWallet, _fsTokensPenaltyToDevWallet); // burn sFS tokens of user sFSToken.burnFrom(msg.sender, _stakedTierFSToken.tokenAmount); // 4. Remove the StakedTierFSToken Object from the mapping delete walletStakedTierFSTokenMapping[msg.sender]; // Emit event emit UnstakedBeforeLockupPeriodFSToken( msg.sender, _fsTokensToReturnToStaker, _fsTokensPenaltyToDevWallet ); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract ITierFactoryFSonic","name":"_tierFactory","type":"address"},{"internalType":"contract IERC20","name":"_fsToken","type":"address"},{"internalType":"contract IERC20","name":"_sFSToken","type":"address"},{"internalType":"address","name":"_devWallet","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"fsTokensStaked","type":"uint256"}],"name":"AddToStakedTierFSToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"nftId","type":"uint256"}],"name":"AddToStakedTierNFT","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldCoolDownDays","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newCoolDownDays","type":"uint256"}],"name":"ChangedCoolDownDays","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"address","name":"oldDevWalletAddress","type":"address"},{"indexed":false,"internalType":"address","name":"newDevWalletAddress","type":"address"}],"name":"ChangedDevWalletAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldLockupFactoryDays","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newLockupFactoryDays","type":"uint256"}],"name":"ChangedLockupDays","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"contract ITierFactoryFSonic","name":"oldTierFactoryAddress","type":"address"},{"indexed":false,"internalType":"contract ITierFactoryFSonic","name":"newTierFactoryAddress","type":"address"}],"name":"ChangedTierFactoryAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldUnstakingPercentage","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newUnstakingPercentage","type":"uint256"}],"name":"ChangedWithholdUnstakingPercentage","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"fsTokensStaked","type":"uint256"}],"name":"RemovedFromStakedTierFSToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"nftId","type":"uint256"}],"name":"RemovedFromStakedTierNFT","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"fsTokensStakedReturned","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"withheldFSTokens","type":"uint256"}],"name":"UnstakedBeforeLockupPeriodFSToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"uint256","name":"tierId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"minFSTokens","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"maxFSTokens","type":"uint256"}],"name":"UpdateOrCreateFSTierTokenRange","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"coolDownDays","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fsToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"}],"name":"getLockupTimeLeftStakedFSTokens","outputs":[{"internalType":"uint256","name":"lockupTimeLeft","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"}],"name":"getLockupTimeLeftStakedNFT","outputs":[{"internalType":"uint256","name":"lockupTimeLeft","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"}],"name":"getNFTIdStaked","outputs":[{"internalType":"uint256","name":"nftIdStaked","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"}],"name":"getTierBenefitForStaker","outputs":[{"internalType":"uint256","name":"tierId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTierFSTokens","outputs":[{"components":[{"internalType":"bool","name":"initialized","type":"bool"},{"internalType":"uint256","name":"tierId","type":"uint256"},{"internalType":"uint256","name":"minFSTokens","type":"uint256"},{"internalType":"uint256","name":"maxFSTokens","type":"uint256"}],"internalType":"struct StakerTierFSonic.TierFSTokens[]","name":"tierFSTokens","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokensStaked","type":"uint256"}],"name":"getTierIdFromTokensStaked","outputs":[{"internalType":"uint256","name":"tierId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"}],"name":"getTokensAmountStaked","outputs":[{"internalType":"uint256","name":"tokenAmountStaked","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"}],"name":"hasCancelCoolDownDaysExpiredForStakedNFT","outputs":[{"internalType":"bool","name":"expired","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"}],"name":"hasWalletCompletedStakingFSTokens","outputs":[{"internalType":"bool","name":"hasCompletedStakingFSTokens","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"}],"name":"hasWalletCompletedStakingNFT","outputs":[{"internalType":"bool","name":"hasCompletedStakingNFT","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"}],"name":"hasWalletCurrentlyStakedFSTokens","outputs":[{"internalType":"bool","name":"hasStakedFSTokens","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"}],"name":"hasWalletCurrentlyStakedNFT","outputs":[{"internalType":"bool","name":"hasStakedNFT","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockupDays","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sFSToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_days","type":"uint256"}],"name":"setCoolDownDays","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_devWallet","type":"address"}],"name":"setDevWalletAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_days","type":"uint256"}],"name":"setLockupDays","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tierId","type":"uint256"},{"internalType":"uint256","name":"_minFSTokens","type":"uint256"},{"internalType":"uint256","name":"_maxFSTokens","type":"uint256"}],"name":"setTierFSTokenRange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ITierFactoryFSonic","name":"_tierFactory","type":"address"}],"name":"setTierFactoryAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_withholdUnstakingPercentage","type":"uint256"}],"name":"setWithholdUnstakingPercentage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fsTokenAmountToStake","type":"uint256"}],"name":"stakeTierFSTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nftId","type":"uint256"}],"name":"stakeTierNFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tierFSTokensList","outputs":[{"internalType":"bool","name":"initialized","type":"bool"},{"internalType":"uint256","name":"tierId","type":"uint256"},{"internalType":"uint256","name":"minFSTokens","type":"uint256"},{"internalType":"uint256","name":"maxFSTokens","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tierFactory","outputs":[{"internalType":"contract ITierFactoryFSonic","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unstakeTierFSTokensAfterLockupPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unstakeTierFSTokensBeforeLockupPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unstakeTierNFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fsTokenAmountToStake","type":"uint256"}],"name":"updateCurrentStakedFSTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"walletStakedTierFSTokenMapping","outputs":[{"internalType":"bool","name":"currentlyStaked","type":"bool"},{"internalType":"uint256","name":"tokenAmount","type":"uint256"},{"internalType":"uint256","name":"tierId","type":"uint256"},{"internalType":"uint256","name":"withholdUnstakingPercentage","type":"uint256"},{"internalType":"uint256","name":"creationTimestamp","type":"uint256"},{"internalType":"uint256","name":"stakingLockupDays","type":"uint256"},{"internalType":"uint256","name":"cancelStackingCoolDownDays","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"walletStakedTierNFTMapping","outputs":[{"internalType":"bool","name":"currentlyStaked","type":"bool"},{"internalType":"uint256","name":"nftId","type":"uint256"},{"internalType":"uint256","name":"tierId","type":"uint256"},{"internalType":"uint256","name":"creationTimestamp","type":"uint256"},{"internalType":"uint256","name":"stakingLockupDays","type":"uint256"},{"internalType":"uint256","name":"cancelStackingCoolDownDays","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withholdUnstakingPercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405260076004556000600555600a6006553480156200002057600080fd5b50604051620033783803806200337883398101604081905262000043916200016d565b62000050600033620000a4565b600180546001600160a01b039586166001600160a01b0319918216179091556002805494861694821694909417909355600380549285169284169290921790915560078054919093169116179055620001d5565b620000b08282620000b4565b5050565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16620000b0576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055620001103390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6001600160a01b03811681146200016a57600080fd5b50565b600080600080608085870312156200018457600080fd5b8451620001918162000154565b6020860151909450620001a48162000154565b6040860151909350620001b78162000154565b6060860151909250620001ca8162000154565b939692955090935050565b61319380620001e56000396000f3fe608060405234801561001057600080fd5b506004361061025e5760003560e01c8063842b047e11610146578063bc197c81116100c3578063d87b59cc11610087578063d87b59cc14610631578063d92456cb14610644578063ddadd90f14610657578063e1a4f14a1461066a578063e406bbbd1461067d578063f23a6e611461069057600080fd5b8063bc197c8114610545578063c213fa591461057d578063d0dd52aa14610585578063d547741f1461060b578063d859345f1461061e57600080fd5b806398bc695d1161010a57806398bc695d146104fb578063a217fddf14610504578063a2b70e591461050c578063b55c4eb51461051f578063b96437b41461053257600080fd5b8063842b047e146104a557806390273901146104b857806391d14854146104c057806393c310b7146104d35780639627ffe9146104e657600080fd5b806336568abe116101df578063554a7060116101a3578063554a706014610403578063583d5a8314610416578063587e77361461041f5780635a2f80a01461043257806373ef9e0f1461044557806374f10eb11461047057600080fd5b806336568abe1461034c5780634409eea11461035f57806346d77162146103675780635040df9a1461037a578063523280861461038d57600080fd5b8063201d607611610226578063201d6076146102dd578063248a9ca3146102f05780632d52f68c146103135780632f2ff15d1461032657806335f63aff1461033957600080fd5b806301de23511461026357806301ffc9a71461027f57806311983e53146102a257806311aec429146102b5578063120a0612146102ca575b600080fd5b61026c60055481565b6040519081526020015b60405180910390f35b61029261028d36600461298e565b6106af565b6040519015158152602001610276565b61026c6102b03660046129d0565b6106c0565b6102c86102c33660046129ed565b6107ea565b005b6102c86102d83660046129d0565b610859565b6102c86102eb366004612a06565b6108e1565b61026c6102fe3660046129ed565b60009081526020819052604090206001015490565b61026c6103213660046129d0565b610aea565b6102c8610334366004612a32565b610c01565b6102c86103473660046129ed565b610c2c565b6102c861035a366004612a32565b610e7d565b6102c8610efb565b6102c86103753660046129ed565b611219565b6102926103883660046129d0565b6114dc565b6103d461039b3660046129d0565b60096020526000908152604090208054600182015460028301546003840154600485015460059095015460ff9094169492939192909186565b6040805196151587526020870195909552938501929092526060840152608083015260a082015260c001610276565b6102c86104113660046129ed565b611571565b61026c60065481565b61029261042d3660046129d0565b611696565b6102c86104403660046129ed565b6117be565b600254610458906001600160a01b031681565b6040516001600160a01b039091168152602001610276565b61048361047e3660046129ed565b611821565b6040805194151585526020850193909352918301526060820152608001610276565b600154610458906001600160a01b031681565b6102c861185f565b6102926104ce366004612a32565b611a8e565b61026c6104e13660046129d0565b611ab7565b6104ee611b28565b6040516102769190612a62565b61026c60045481565b61026c600081565b6102c861051a3660046129d0565b611bae565b61029261052d3660046129d0565b611c36565b600354610458906001600160a01b031681565b610564610553366004612bf4565b63bc197c8160e01b95945050505050565b6040516001600160e01b03199091168152602001610276565b6102c8611c66565b6105d46105933660046129d0565b600a60205260009081526040902080546001820154600283015460038401546004850154600586015460069096015460ff9095169593949293919290919087565b6040805197151588526020880196909652948601939093526060850191909152608084015260a083015260c082015260e001610276565b6102c8610619366004612a32565b611eff565b61026c61062c3660046129d0565b611f25565b6102c861063f3660046129ed565b611f96565b6102926106523660046129d0565b6121aa565b6102926106653660046129d0565b612238565b61026c6106783660046129ed565b612268565b61026c61068b3660046129d0565b612312565b61056461069e366004612ca2565b63f23a6e6160e01b95945050505050565b60006106ba826123de565b92915050565b60006106cb82612238565b15156001146106f55760405162461bcd60e51b81526004016106ec90612d0b565b60405180910390fd5b6106fe82611c36565b1561071b5760405162461bcd60e51b81526004016106ec90612d4d565b6001600160a01b0382166000908152600960209081526040808320815160c081018352815460ff16151581526001820154938101939093526002810154918301919091526003810154606083015260048101546080830181905260059091015460a0830152909190819042906107949062015180612dab565b84606001516107a39190612dc2565b6107ad9190612dd5565b11156107e357428260800151620151806107c79190612dab565b83606001516107d69190612dc2565b6107e09190612dd5565b90505b9392505050565b6107f5600033611a8e565b6108115760405162461bcd60e51b81526004016106ec90612de8565b60048054908290556040517f339b9229beac0da59bc8ab4913b1e81b018cae9ecef830c573c53deeb87f5c529061084d90339084908690612e1d565b60405180910390a15050565b610864600033611a8e565b6108805760405162461bcd60e51b81526004016106ec90612de8565b600780546001600160a01b031981166001600160a01b0384811691821790935560408051338152939092166020840181905291830152907f51b66e0e5bd72224dd75c35b693ad62bd75766bdb04230e2c8c218752c51408a9060600161084d565b6108ec600033611a8e565b6109085760405162461bcd60e51b81526004016106ec90612de8565b60008060005b60085481101561096157856008828154811061092c5761092c612e3e565b9060005260206000209060040201600101540361094f5780915060019250610961565b8061095981612e54565b91505061090e565b5081156109bf57836008828154811061097c5761097c612e3e565b90600052602060002090600402016002018190555082600882815481106109a5576109a5612e3e565b906000526020600020906004020160030181905550610a9b565b604080516080810182526001808252602082018881529282018781526060830187815260088054938401815560005292517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee36004909302928301805460ff191691151591909117905592517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee482015591517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee5830155517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee6909101555b6040805133815260208101879052908101859052606081018490527ffd30965e9c468e5413ad2a3fa0324386fcf45de8135726765a66c121bf9b09e39060800160405180910390a15050505050565b6000610af582612238565b15610b125760405162461bcd60e51b81526004016106ec90612e6d565b610b1b82611c36565b1515600114610b3c5760405162461bcd60e51b81526004016106ec90612eb5565b6001600160a01b0382166000908152600a60209081526040808320815160e081018352815460ff16151581526001820154938101939093526002810154918301919091526003810154606083015260048101546080830152600581015460a0830181905260069091015460c083015290919081904290610bbf9062015180612dab565b8460800151610bce9190612dc2565b610bd89190612dd5565b11156107e357428260a0015162015180610bf29190612dab565b83608001516107d69190612dc2565b600082815260208190526040902060010154610c1d8133612403565b610c278383612467565b505050565b6002546040516370a0823160e01b815233600482015282916001600160a01b0316906370a0823190602401602060405180830381865afa158015610c74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c989190612efd565b1015610cb65760405162461bcd60e51b81526004016106ec90612f16565b610cbf33612238565b15610cdc5760405162461bcd60e51b81526004016106ec90612f5b565b610ce533611c36565b15610d325760405162461bcd60e51b815260206004820181905260248201527f596f75206861766520616c7265616479207374616b6564204653546f6b656e7360448201526064016106ec565b600254610d4a906001600160a01b03163330846124eb565b600354604051630f38ca0d60e31b81526001600160a01b03909116906379c6506890610d7c9033908590600401612f92565b600060405180830381600087803b158015610d9657600080fd5b505af1158015610daa573d6000803e3d6000fd5b505050506000610db982612268565b6040805160e08101825260018082526020808301878152838501868152600680546060870190815242608088019081526004805460a08a019081526005805460c08c01908152336000818152600a909b52998d90209b518c5460ff1916901515178c559751998b0199909955945160028a015591516003890155519087015590519385019390935551929091019190915590519192507f7d9127a72910ce617963edba28318ea738f771668f124319bd636c523b24ac0b9161084d91908590612f92565b6001600160a01b0381163314610eed5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016106ec565b610ef7828261255c565b5050565b610f0433611c36565b1515600114610f555760405162461bcd60e51b815260206004820152601b60248201527f596f752068617665206e6f204653546f6b656e73207374616b6564000000000060448201526064016106ec565b610f5e336121aa565b15610fab5760405162461bcd60e51b815260206004820152601960248201527f4c6f636b757020706572696f642068617320657870697265640000000000000060448201526064016106ec565b336000818152600a6020908152604091829020825160e081018452815460ff1615158152600182015492810183905260028201548185015260038083015460608301526004808401546080840152600584015460a084015260069093015460c08301525493516370a0823160e01b81529182019490945290916001600160a01b0316906370a0823190602401602060405180830381865afa158015611054573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110789190612efd565b10156110c65760405162461bcd60e51b815260206004820181905260248201527f596f7520646f6e2774206861766520656e6f7567682073465320746f6b656e2160448201526064016106ec565b6000806064836060015184602001516110df9190612dab565b6110e99190612fab565b90508083602001516110fb9190612dd5565b600254909250611115906001600160a01b031633846125c1565b600754600254611132916001600160a01b039182169116836125c1565b600354602084015160405163079cc67960e41b81526001600160a01b03909216916379cc67909161116891339190600401612f92565b600060405180830381600087803b15801561118257600080fd5b505af1158015611196573d6000803e3d6000fd5b5050336000818152600a6020526040808220805460ff19168155600181018390556002810183905560038101839055600481018390556005810183905560060191909155517fa20e94ac360e12a963d3b1a4111d5d6cebcab4db627c9a6479c6dad34610c7f1935061120c925085908590612e1d565b60405180910390a1505050565b600154604051627eeac760e11b81526000916001600160a01b03169062fdd58e9061124a9033908690600401612f92565b602060405180830381865afa158015611267573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061128b9190612efd565b116112d85760405162461bcd60e51b815260206004820152601760248201527f596f7520646f206e6f74206f776e2074686973204e465400000000000000000060448201526064016106ec565b6112e133612238565b156112fe5760405162461bcd60e51b81526004016106ec90612f5b565b61130733611c36565b156113545760405162461bcd60e51b815260206004820181905260248201527f596f75206861766520616c7265616479207374616b6564204653546f6b656e7360448201526064016106ec565b60018054604051637921219560e11b81526001600160a01b039091169163f242432a9161138991339130918791600401612fcd565b600060405180830381600087803b1580156113a357600080fd5b505af11580156113b7573d6000803e3d6000fd5b5050600154604051634551169d60e01b815260048101859052600093506001600160a01b039091169150634551169d90602401602060405180830381865afa158015611407573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061142b9190612efd565b6040805160c08101825260018082526020808301878152838501868152426060860190815260048054608088019081526005805460a08a019081523360008181526009909952978b902099518a5460ff1916901515178a55955197890197909755925160028801559051600387015590519085015551929091019190915590519192507fae60b3ca24281aea6e75782e0e5a980a7dd9ee173e63fb212a8c0def1fc6efe79161084d91908590612f92565b6001600160a01b0381166000908152600960209081526040808320815160c081018352815460ff1615158152600182810154948201949094526002820154928101929092526003810154606083015260048101546080830181905260059091015460a083015242906115519062015180612dab565b82606001516115609190612dc2565b1061156a57600091505b5092915050565b61157c600033611a8e565b6115985760405162461bcd60e51b81526004016106ec90612de8565b606481106115f95760405162461bcd60e51b815260206004820152602860248201527f596f752063616e6e6f742077697468686f6c64206d6f7265207468616e203939604482015267081c195c98d95b9d60c21b60648201526084016106ec565b600181101561165a5760405162461bcd60e51b815260206004820152602760248201527f596f75206e65656420746f2077697468686f6c64206174206c656173742031206044820152661c195c98d95b9d60ca1b60648201526084016106ec565b60068054908290556040517fbed291e013058f2243e71b2170f425b3c4819b155f012b92e4492b3ad3e866849061084d90339084908690612e1d565b60006116a182612238565b15156001146116f25760405162461bcd60e51b815260206004820181905260248201527f596f7520686176652063757272656e746c79206e6f204e4654207374616b656460448201526064016106ec565b6116fb826114dc565b151560011461171c5760405162461bcd60e51b81526004016106ec90613005565b6001600160a01b038216600090815260096020908152604091829020825160c081018452815460ff16151581526001828101549382019390935260028201549381019390935260038101546060840152600481015460808401526005015460a0830181905290919042906117939062015180612dab565b60808301516117a59062015180612dab565b83606001516117b49190612dc2565b6115609190612dc2565b6117c9600033611a8e565b6117e55760405162461bcd60e51b81526004016106ec90612de8565b60058054908290556040517fdb8d38150b9bb879c12291844bcd9c914b7c4666ae198f4db69a5a5176d13ee89061084d90339084908690612e1d565b6008818154811061183157600080fd5b6000918252602090912060049091020180546001820154600283015460039093015460ff9092169350919084565b61186833612238565b15156001146118b95760405162461bcd60e51b815260206004820181905260248201527f596f7520686176652063757272656e746c79206e6f204e4654207374616b656460448201526064016106ec565b6118c2336114dc565b15156001146118e35760405162461bcd60e51b81526004016106ec90613005565b6118ec33611696565b15156001146119595760405162461bcd60e51b815260206004820152603360248201527f596f75206e65656420746f207761697420666f722074686520636f6f6c20646f604482015272776e20706572696f6420746f2065787069726560681b60648201526084016106ec565b33600081815260096020908152604091829020825160c081018452815460ff161515815260018083015493820184905260028301548286015260038301546060830152600480840154608084015260059093015460a083015280549451637921219560e11b815291956001600160a01b039095169463f242432a946119e49430949293919201612fcd565b600060405180830381600087803b1580156119fe57600080fd5b505af1158015611a12573d6000803e3d6000fd5b5050336000818152600960209081526040808320805460ff19168155600181018490556002810184905560038101849055600481018490556005019290925585015190517fb04b58934e9f7d959ec5e18634b0bc7164b689fa752fd45d2f20f8ccfa33cab19450611a839350612f92565b60405180910390a150565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b6000611ac282612238565b15611adf5760405162461bcd60e51b81526004016106ec90612e6d565b611ae882611c36565b1515600114611b095760405162461bcd60e51b81526004016106ec90612eb5565b506001600160a01b03166000908152600a602052604090206001015490565b60606008805480602002602001604051908101604052809291908181526020016000905b82821015611ba55760008481526020908190206040805160808101825260048602909201805460ff1615158352600180820154848601526002820154928401929092526003015460608301529083529092019101611b4c565b50505050905090565b611bb9600033611a8e565b611bd55760405162461bcd60e51b81526004016106ec90612de8565b600180546001600160a01b031981166001600160a01b0384811691821790935560408051338152939092166020840181905291830152907f9d5e5e35ff4b9029875bfd320e82316168739f50ec7d9b2847a08542967036789060600161084d565b6001600160a01b0381166000908152600a6020526040812054819060ff1615156001036106ba5750600192915050565b611c6f33611c36565b1515600114611cc05760405162461bcd60e51b815260206004820152601b60248201527f596f752068617665206e6f204653546f6b656e73207374616b6564000000000060448201526064016106ec565b611cc9336121aa565b1515600114611cea5760405162461bcd60e51b81526004016106ec90613005565b336000818152600a6020908152604091829020825160e081018452815460ff1615158152600182015492810183905260028201548185015260038083015460608301526004808401546080840152600584015460a084015260069093015460c08301525493516370a0823160e01b81529182019490945290916001600160a01b0316906370a0823190602401602060405180830381865afa158015611d93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611db79190612efd565b1015611e055760405162461bcd60e51b815260206004820181905260248201527f596f7520646f6e2774206861766520656e6f7567682073465320746f6b656e2160448201526064016106ec565b6020810151600254611e24916001600160a01b039091169033906125c1565b600354602082015160405163079cc67960e41b81526001600160a01b03909216916379cc679091611e5a91339190600401612f92565b600060405180830381600087803b158015611e7457600080fd5b505af1158015611e88573d6000803e3d6000fd5b5050336000818152600a60209081526040808320805460ff1916815560018101849055600281018490556003810184905560048101849055600581018490556006019290925585015190517e0394400365c07f75e43823dbaaeed7ca6913196a36451c4a64bf7a09e6de8e9450611a839350612f92565b600082815260208190526040902060010154611f1b8133612403565b610c27838361255c565b6000611f3082612238565b1515600114611f515760405162461bcd60e51b81526004016106ec90612d0b565b611f5a82611c36565b15611f775760405162461bcd60e51b81526004016106ec90612d4d565b506001600160a01b031660009081526009602052604090206001015490565b6002546040516370a0823160e01b815233600482015282916001600160a01b0316906370a0823190602401602060405180830381865afa158015611fde573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120029190612efd565b10156120205760405162461bcd60e51b81526004016106ec90612f16565b61202933612238565b156120465760405162461bcd60e51b81526004016106ec90612f5b565b61204f33611c36565b15156001146120a05760405162461bcd60e51b815260206004820152601f60248201527f596f7520646f206e6f742068617665207374616b6564204653546f6b656e730060448201526064016106ec565b6002546120b8906001600160a01b03163330846124eb565b600354604051630f38ca0d60e31b81526001600160a01b03909116906379c65068906120ea9033908590600401612f92565b600060405180830381600087803b15801561210457600080fd5b505af1158015612118573d6000803e3d6000fd5b5050336000908152600a602052604090206001015461213a9250839150612dc2565b336000908152600a602052604081206001018290559061215990612268565b336000818152600a6020526040908190206002810184905542600490910155519192507f7d9127a72910ce617963edba28318ea738f771668f124319bd636c523b24ac0b9161084d91908590612f92565b6001600160a01b0381166000908152600a60209081526040808320815160e081018352815460ff1615158152600182810154948201949094526002820154928101929092526003810154606083015260048101546080830152600581015460a0830181905260069091015460c083015242906122299062015180612dab565b82608001516115609190612dc2565b6001600160a01b038116600090815260096020526040812054819060ff1615156001036106ba5750600192915050565b600080805b60085481101561156a576008818154811061228a5761228a612e3e565b90600052602060002090600402016002015484101580156122cf5750600881815481106122b9576122b9612e3e565b9060005260206000209060040201600301548411155b1561230057600881815481106122e7576122e7612e3e565b906000526020600020906004020160010154915061156a565b8061230a81612e54565b91505061226d565b60008061231e83612238565b156123a3576001546001600160a01b0316634551169d61233d85611f25565b6040518263ffffffff1660e01b815260040161235b91815260200190565b602060405180830381865afa158015612378573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239c9190612efd565b90506106ba565b6123ac83611c36565b156106ba576001600160a01b0383166000908152600a60205260409020600101546123d681612268565b949350505050565b60006001600160e01b03198216637965db0b60e01b14806106ba57506106ba826125e0565b61240d8282611a8e565b610ef757612425816001600160a01b03166014612615565b612430836020612615565b604051602001612441929190613060565b60408051601f198184030181529082905262461bcd60e51b82526106ec916004016130d5565b6124718282611a8e565b610ef7576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556124a73390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6040516001600160a01b03808516602483015283166044820152606481018290526125569085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526127b1565b50505050565b6125668282611a8e565b15610ef7576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b610c278363a9059cbb60e01b848460405160240161251f929190612f92565b60006001600160e01b03198216630271189760e51b14806106ba57506301ffc9a760e01b6001600160e01b03198316146106ba565b60606000612624836002612dab565b61262f906002612dc2565b67ffffffffffffffff81111561264757612647612ac8565b6040519080825280601f01601f191660200182016040528015612671576020820181803683370190505b509050600360fc1b8160008151811061268c5761268c612e3e565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106126bb576126bb612e3e565b60200101906001600160f81b031916908160001a90535060006126df846002612dab565b6126ea906001612dc2565b90505b6001811115612762576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061271e5761271e612e3e565b1a60f81b82828151811061273457612734612e3e565b60200101906001600160f81b031916908160001a90535060049490941c9361275b81613108565b90506126ed565b5083156107e35760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016106ec565b6000612806826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166128839092919063ffffffff16565b805190915015610c275780806020019051810190612824919061311f565b610c275760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016106ec565b60606107e0848460008585843b6128dc5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016106ec565b600080866001600160a01b031685876040516128f89190613141565b60006040518083038185875af1925050503d8060008114612935576040519150601f19603f3d011682016040523d82523d6000602084013e61293a565b606091505b509150915061294a828286612955565b979650505050505050565b606083156129645750816107e3565b8251156129745782518084602001fd5b8160405162461bcd60e51b81526004016106ec91906130d5565b6000602082840312156129a057600080fd5b81356001600160e01b0319811681146107e357600080fd5b6001600160a01b03811681146129cd57600080fd5b50565b6000602082840312156129e257600080fd5b81356107e3816129b8565b6000602082840312156129ff57600080fd5b5035919050565b600080600060608486031215612a1b57600080fd5b505081359360208301359350604090920135919050565b60008060408385031215612a4557600080fd5b823591506020830135612a57816129b8565b809150509250929050565b602080825282518282018190526000919060409081850190868401855b82811015612abb578151805115158552868101518786015285810151868601526060908101519085015260809093019290850190600101612a7f565b5091979650505050505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612b0757612b07612ac8565b604052919050565b600082601f830112612b2057600080fd5b8135602067ffffffffffffffff821115612b3c57612b3c612ac8565b8160051b612b4b828201612ade565b9283528481018201928281019087851115612b6557600080fd5b83870192505b8483101561294a57823582529183019190830190612b6b565b600082601f830112612b9557600080fd5b813567ffffffffffffffff811115612baf57612baf612ac8565b612bc2601f8201601f1916602001612ade565b818152846020838601011115612bd757600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a08688031215612c0c57600080fd5b8535612c17816129b8565b94506020860135612c27816129b8565b9350604086013567ffffffffffffffff80821115612c4457600080fd5b612c5089838a01612b0f565b94506060880135915080821115612c6657600080fd5b612c7289838a01612b0f565b93506080880135915080821115612c8857600080fd5b50612c9588828901612b84565b9150509295509295909350565b600080600080600060a08688031215612cba57600080fd5b8535612cc5816129b8565b94506020860135612cd5816129b8565b93506040860135925060608601359150608086013567ffffffffffffffff811115612cff57600080fd5b612c9588828901612b84565b60208082526022908201527f57616c6c6574206861732063757272656e746c79206e6f204e4654207374616b604082015261195960f21b606082015260800190565b60208082526028908201527f57616c6c657420686173207374616b656420465320546f6b656e7320616e64206040820152676e6f74204e46547360c01b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176106ba576106ba612d95565b808201808211156106ba576106ba612d95565b818103818111156106ba576106ba612d95565b6020808252818101527f4163636f756e74206973206e6f7420696e207468652061646d696e206c697374604082015260600190565b6001600160a01b039390931683526020830191909152604082015260600190565b634e487b7160e01b600052603260045260246000fd5b600060018201612e6657612e66612d95565b5060010190565b60208082526028908201527f57616c6c657420686173207374616b6564204e46547320616e64206e6f7420466040820152675320746f6b656e7360c01b606082015260800190565b60208082526028908201527f57616c6c6574206861732063757272656e746c79206e6f20465320546f6b656e6040820152671cc81cdd185ad95960c21b606082015260800190565b600060208284031215612f0f57600080fd5b5051919050565b60208082526025908201527f596f7520646f206e6f74206f776e20656e6f75676820746f6b656e7320746f206040820152647374616b6560d81b606082015260800190565b6020808252601c908201527f596f75206861766520616c7265616479207374616b6564204e46547300000000604082015260600190565b6001600160a01b03929092168252602082015260400190565b600082612fc857634e487b7160e01b600052601260045260246000fd5b500490565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a06080820181905260009082015260c00190565b6020808252601b908201527f4c6f636b757020706572696f64207374696c6c2070656e64696e670000000000604082015260600190565b60005b8381101561305757818101518382015260200161303f565b50506000910152565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161309881601785016020880161303c565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516130c981602884016020880161303c565b01602801949350505050565b60208152600082518060208401526130f481604085016020870161303c565b601f01601f19169190910160400192915050565b60008161311757613117612d95565b506000190190565b60006020828403121561313157600080fd5b815180151581146107e357600080fd5b6000825161315381846020870161303c565b919091019291505056fea264697066735822122067d4062d6fc8607b22438ab1050c07400873052d52dc01ccb20934a8a5b1e69564736f6c634300081200330000000000000000000000004db1e329713f3b4d606f3d3956eed3eca7dc6e99000000000000000000000000bc0d0650412ef353d672c0bbd12efff90591b251000000000000000000000000a81b289dc053c242b43aed38f2b77e30dd459ec10000000000000000000000006e2a0a942eaa01b7eb2639b8b65d1d2768a87bac
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061025e5760003560e01c8063842b047e11610146578063bc197c81116100c3578063d87b59cc11610087578063d87b59cc14610631578063d92456cb14610644578063ddadd90f14610657578063e1a4f14a1461066a578063e406bbbd1461067d578063f23a6e611461069057600080fd5b8063bc197c8114610545578063c213fa591461057d578063d0dd52aa14610585578063d547741f1461060b578063d859345f1461061e57600080fd5b806398bc695d1161010a57806398bc695d146104fb578063a217fddf14610504578063a2b70e591461050c578063b55c4eb51461051f578063b96437b41461053257600080fd5b8063842b047e146104a557806390273901146104b857806391d14854146104c057806393c310b7146104d35780639627ffe9146104e657600080fd5b806336568abe116101df578063554a7060116101a3578063554a706014610403578063583d5a8314610416578063587e77361461041f5780635a2f80a01461043257806373ef9e0f1461044557806374f10eb11461047057600080fd5b806336568abe1461034c5780634409eea11461035f57806346d77162146103675780635040df9a1461037a578063523280861461038d57600080fd5b8063201d607611610226578063201d6076146102dd578063248a9ca3146102f05780632d52f68c146103135780632f2ff15d1461032657806335f63aff1461033957600080fd5b806301de23511461026357806301ffc9a71461027f57806311983e53146102a257806311aec429146102b5578063120a0612146102ca575b600080fd5b61026c60055481565b6040519081526020015b60405180910390f35b61029261028d36600461298e565b6106af565b6040519015158152602001610276565b61026c6102b03660046129d0565b6106c0565b6102c86102c33660046129ed565b6107ea565b005b6102c86102d83660046129d0565b610859565b6102c86102eb366004612a06565b6108e1565b61026c6102fe3660046129ed565b60009081526020819052604090206001015490565b61026c6103213660046129d0565b610aea565b6102c8610334366004612a32565b610c01565b6102c86103473660046129ed565b610c2c565b6102c861035a366004612a32565b610e7d565b6102c8610efb565b6102c86103753660046129ed565b611219565b6102926103883660046129d0565b6114dc565b6103d461039b3660046129d0565b60096020526000908152604090208054600182015460028301546003840154600485015460059095015460ff9094169492939192909186565b6040805196151587526020870195909552938501929092526060840152608083015260a082015260c001610276565b6102c86104113660046129ed565b611571565b61026c60065481565b61029261042d3660046129d0565b611696565b6102c86104403660046129ed565b6117be565b600254610458906001600160a01b031681565b6040516001600160a01b039091168152602001610276565b61048361047e3660046129ed565b611821565b6040805194151585526020850193909352918301526060820152608001610276565b600154610458906001600160a01b031681565b6102c861185f565b6102926104ce366004612a32565b611a8e565b61026c6104e13660046129d0565b611ab7565b6104ee611b28565b6040516102769190612a62565b61026c60045481565b61026c600081565b6102c861051a3660046129d0565b611bae565b61029261052d3660046129d0565b611c36565b600354610458906001600160a01b031681565b610564610553366004612bf4565b63bc197c8160e01b95945050505050565b6040516001600160e01b03199091168152602001610276565b6102c8611c66565b6105d46105933660046129d0565b600a60205260009081526040902080546001820154600283015460038401546004850154600586015460069096015460ff9095169593949293919290919087565b6040805197151588526020880196909652948601939093526060850191909152608084015260a083015260c082015260e001610276565b6102c8610619366004612a32565b611eff565b61026c61062c3660046129d0565b611f25565b6102c861063f3660046129ed565b611f96565b6102926106523660046129d0565b6121aa565b6102926106653660046129d0565b612238565b61026c6106783660046129ed565b612268565b61026c61068b3660046129d0565b612312565b61056461069e366004612ca2565b63f23a6e6160e01b95945050505050565b60006106ba826123de565b92915050565b60006106cb82612238565b15156001146106f55760405162461bcd60e51b81526004016106ec90612d0b565b60405180910390fd5b6106fe82611c36565b1561071b5760405162461bcd60e51b81526004016106ec90612d4d565b6001600160a01b0382166000908152600960209081526040808320815160c081018352815460ff16151581526001820154938101939093526002810154918301919091526003810154606083015260048101546080830181905260059091015460a0830152909190819042906107949062015180612dab565b84606001516107a39190612dc2565b6107ad9190612dd5565b11156107e357428260800151620151806107c79190612dab565b83606001516107d69190612dc2565b6107e09190612dd5565b90505b9392505050565b6107f5600033611a8e565b6108115760405162461bcd60e51b81526004016106ec90612de8565b60048054908290556040517f339b9229beac0da59bc8ab4913b1e81b018cae9ecef830c573c53deeb87f5c529061084d90339084908690612e1d565b60405180910390a15050565b610864600033611a8e565b6108805760405162461bcd60e51b81526004016106ec90612de8565b600780546001600160a01b031981166001600160a01b0384811691821790935560408051338152939092166020840181905291830152907f51b66e0e5bd72224dd75c35b693ad62bd75766bdb04230e2c8c218752c51408a9060600161084d565b6108ec600033611a8e565b6109085760405162461bcd60e51b81526004016106ec90612de8565b60008060005b60085481101561096157856008828154811061092c5761092c612e3e565b9060005260206000209060040201600101540361094f5780915060019250610961565b8061095981612e54565b91505061090e565b5081156109bf57836008828154811061097c5761097c612e3e565b90600052602060002090600402016002018190555082600882815481106109a5576109a5612e3e565b906000526020600020906004020160030181905550610a9b565b604080516080810182526001808252602082018881529282018781526060830187815260088054938401815560005292517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee36004909302928301805460ff191691151591909117905592517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee482015591517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee5830155517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee6909101555b6040805133815260208101879052908101859052606081018490527ffd30965e9c468e5413ad2a3fa0324386fcf45de8135726765a66c121bf9b09e39060800160405180910390a15050505050565b6000610af582612238565b15610b125760405162461bcd60e51b81526004016106ec90612e6d565b610b1b82611c36565b1515600114610b3c5760405162461bcd60e51b81526004016106ec90612eb5565b6001600160a01b0382166000908152600a60209081526040808320815160e081018352815460ff16151581526001820154938101939093526002810154918301919091526003810154606083015260048101546080830152600581015460a0830181905260069091015460c083015290919081904290610bbf9062015180612dab565b8460800151610bce9190612dc2565b610bd89190612dd5565b11156107e357428260a0015162015180610bf29190612dab565b83608001516107d69190612dc2565b600082815260208190526040902060010154610c1d8133612403565b610c278383612467565b505050565b6002546040516370a0823160e01b815233600482015282916001600160a01b0316906370a0823190602401602060405180830381865afa158015610c74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c989190612efd565b1015610cb65760405162461bcd60e51b81526004016106ec90612f16565b610cbf33612238565b15610cdc5760405162461bcd60e51b81526004016106ec90612f5b565b610ce533611c36565b15610d325760405162461bcd60e51b815260206004820181905260248201527f596f75206861766520616c7265616479207374616b6564204653546f6b656e7360448201526064016106ec565b600254610d4a906001600160a01b03163330846124eb565b600354604051630f38ca0d60e31b81526001600160a01b03909116906379c6506890610d7c9033908590600401612f92565b600060405180830381600087803b158015610d9657600080fd5b505af1158015610daa573d6000803e3d6000fd5b505050506000610db982612268565b6040805160e08101825260018082526020808301878152838501868152600680546060870190815242608088019081526004805460a08a019081526005805460c08c01908152336000818152600a909b52998d90209b518c5460ff1916901515178c559751998b0199909955945160028a015591516003890155519087015590519385019390935551929091019190915590519192507f7d9127a72910ce617963edba28318ea738f771668f124319bd636c523b24ac0b9161084d91908590612f92565b6001600160a01b0381163314610eed5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016106ec565b610ef7828261255c565b5050565b610f0433611c36565b1515600114610f555760405162461bcd60e51b815260206004820152601b60248201527f596f752068617665206e6f204653546f6b656e73207374616b6564000000000060448201526064016106ec565b610f5e336121aa565b15610fab5760405162461bcd60e51b815260206004820152601960248201527f4c6f636b757020706572696f642068617320657870697265640000000000000060448201526064016106ec565b336000818152600a6020908152604091829020825160e081018452815460ff1615158152600182015492810183905260028201548185015260038083015460608301526004808401546080840152600584015460a084015260069093015460c08301525493516370a0823160e01b81529182019490945290916001600160a01b0316906370a0823190602401602060405180830381865afa158015611054573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110789190612efd565b10156110c65760405162461bcd60e51b815260206004820181905260248201527f596f7520646f6e2774206861766520656e6f7567682073465320746f6b656e2160448201526064016106ec565b6000806064836060015184602001516110df9190612dab565b6110e99190612fab565b90508083602001516110fb9190612dd5565b600254909250611115906001600160a01b031633846125c1565b600754600254611132916001600160a01b039182169116836125c1565b600354602084015160405163079cc67960e41b81526001600160a01b03909216916379cc67909161116891339190600401612f92565b600060405180830381600087803b15801561118257600080fd5b505af1158015611196573d6000803e3d6000fd5b5050336000818152600a6020526040808220805460ff19168155600181018390556002810183905560038101839055600481018390556005810183905560060191909155517fa20e94ac360e12a963d3b1a4111d5d6cebcab4db627c9a6479c6dad34610c7f1935061120c925085908590612e1d565b60405180910390a1505050565b600154604051627eeac760e11b81526000916001600160a01b03169062fdd58e9061124a9033908690600401612f92565b602060405180830381865afa158015611267573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061128b9190612efd565b116112d85760405162461bcd60e51b815260206004820152601760248201527f596f7520646f206e6f74206f776e2074686973204e465400000000000000000060448201526064016106ec565b6112e133612238565b156112fe5760405162461bcd60e51b81526004016106ec90612f5b565b61130733611c36565b156113545760405162461bcd60e51b815260206004820181905260248201527f596f75206861766520616c7265616479207374616b6564204653546f6b656e7360448201526064016106ec565b60018054604051637921219560e11b81526001600160a01b039091169163f242432a9161138991339130918791600401612fcd565b600060405180830381600087803b1580156113a357600080fd5b505af11580156113b7573d6000803e3d6000fd5b5050600154604051634551169d60e01b815260048101859052600093506001600160a01b039091169150634551169d90602401602060405180830381865afa158015611407573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061142b9190612efd565b6040805160c08101825260018082526020808301878152838501868152426060860190815260048054608088019081526005805460a08a019081523360008181526009909952978b902099518a5460ff1916901515178a55955197890197909755925160028801559051600387015590519085015551929091019190915590519192507fae60b3ca24281aea6e75782e0e5a980a7dd9ee173e63fb212a8c0def1fc6efe79161084d91908590612f92565b6001600160a01b0381166000908152600960209081526040808320815160c081018352815460ff1615158152600182810154948201949094526002820154928101929092526003810154606083015260048101546080830181905260059091015460a083015242906115519062015180612dab565b82606001516115609190612dc2565b1061156a57600091505b5092915050565b61157c600033611a8e565b6115985760405162461bcd60e51b81526004016106ec90612de8565b606481106115f95760405162461bcd60e51b815260206004820152602860248201527f596f752063616e6e6f742077697468686f6c64206d6f7265207468616e203939604482015267081c195c98d95b9d60c21b60648201526084016106ec565b600181101561165a5760405162461bcd60e51b815260206004820152602760248201527f596f75206e65656420746f2077697468686f6c64206174206c656173742031206044820152661c195c98d95b9d60ca1b60648201526084016106ec565b60068054908290556040517fbed291e013058f2243e71b2170f425b3c4819b155f012b92e4492b3ad3e866849061084d90339084908690612e1d565b60006116a182612238565b15156001146116f25760405162461bcd60e51b815260206004820181905260248201527f596f7520686176652063757272656e746c79206e6f204e4654207374616b656460448201526064016106ec565b6116fb826114dc565b151560011461171c5760405162461bcd60e51b81526004016106ec90613005565b6001600160a01b038216600090815260096020908152604091829020825160c081018452815460ff16151581526001828101549382019390935260028201549381019390935260038101546060840152600481015460808401526005015460a0830181905290919042906117939062015180612dab565b60808301516117a59062015180612dab565b83606001516117b49190612dc2565b6115609190612dc2565b6117c9600033611a8e565b6117e55760405162461bcd60e51b81526004016106ec90612de8565b60058054908290556040517fdb8d38150b9bb879c12291844bcd9c914b7c4666ae198f4db69a5a5176d13ee89061084d90339084908690612e1d565b6008818154811061183157600080fd5b6000918252602090912060049091020180546001820154600283015460039093015460ff9092169350919084565b61186833612238565b15156001146118b95760405162461bcd60e51b815260206004820181905260248201527f596f7520686176652063757272656e746c79206e6f204e4654207374616b656460448201526064016106ec565b6118c2336114dc565b15156001146118e35760405162461bcd60e51b81526004016106ec90613005565b6118ec33611696565b15156001146119595760405162461bcd60e51b815260206004820152603360248201527f596f75206e65656420746f207761697420666f722074686520636f6f6c20646f604482015272776e20706572696f6420746f2065787069726560681b60648201526084016106ec565b33600081815260096020908152604091829020825160c081018452815460ff161515815260018083015493820184905260028301548286015260038301546060830152600480840154608084015260059093015460a083015280549451637921219560e11b815291956001600160a01b039095169463f242432a946119e49430949293919201612fcd565b600060405180830381600087803b1580156119fe57600080fd5b505af1158015611a12573d6000803e3d6000fd5b5050336000818152600960209081526040808320805460ff19168155600181018490556002810184905560038101849055600481018490556005019290925585015190517fb04b58934e9f7d959ec5e18634b0bc7164b689fa752fd45d2f20f8ccfa33cab19450611a839350612f92565b60405180910390a150565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b6000611ac282612238565b15611adf5760405162461bcd60e51b81526004016106ec90612e6d565b611ae882611c36565b1515600114611b095760405162461bcd60e51b81526004016106ec90612eb5565b506001600160a01b03166000908152600a602052604090206001015490565b60606008805480602002602001604051908101604052809291908181526020016000905b82821015611ba55760008481526020908190206040805160808101825260048602909201805460ff1615158352600180820154848601526002820154928401929092526003015460608301529083529092019101611b4c565b50505050905090565b611bb9600033611a8e565b611bd55760405162461bcd60e51b81526004016106ec90612de8565b600180546001600160a01b031981166001600160a01b0384811691821790935560408051338152939092166020840181905291830152907f9d5e5e35ff4b9029875bfd320e82316168739f50ec7d9b2847a08542967036789060600161084d565b6001600160a01b0381166000908152600a6020526040812054819060ff1615156001036106ba5750600192915050565b611c6f33611c36565b1515600114611cc05760405162461bcd60e51b815260206004820152601b60248201527f596f752068617665206e6f204653546f6b656e73207374616b6564000000000060448201526064016106ec565b611cc9336121aa565b1515600114611cea5760405162461bcd60e51b81526004016106ec90613005565b336000818152600a6020908152604091829020825160e081018452815460ff1615158152600182015492810183905260028201548185015260038083015460608301526004808401546080840152600584015460a084015260069093015460c08301525493516370a0823160e01b81529182019490945290916001600160a01b0316906370a0823190602401602060405180830381865afa158015611d93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611db79190612efd565b1015611e055760405162461bcd60e51b815260206004820181905260248201527f596f7520646f6e2774206861766520656e6f7567682073465320746f6b656e2160448201526064016106ec565b6020810151600254611e24916001600160a01b039091169033906125c1565b600354602082015160405163079cc67960e41b81526001600160a01b03909216916379cc679091611e5a91339190600401612f92565b600060405180830381600087803b158015611e7457600080fd5b505af1158015611e88573d6000803e3d6000fd5b5050336000818152600a60209081526040808320805460ff1916815560018101849055600281018490556003810184905560048101849055600581018490556006019290925585015190517e0394400365c07f75e43823dbaaeed7ca6913196a36451c4a64bf7a09e6de8e9450611a839350612f92565b600082815260208190526040902060010154611f1b8133612403565b610c27838361255c565b6000611f3082612238565b1515600114611f515760405162461bcd60e51b81526004016106ec90612d0b565b611f5a82611c36565b15611f775760405162461bcd60e51b81526004016106ec90612d4d565b506001600160a01b031660009081526009602052604090206001015490565b6002546040516370a0823160e01b815233600482015282916001600160a01b0316906370a0823190602401602060405180830381865afa158015611fde573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120029190612efd565b10156120205760405162461bcd60e51b81526004016106ec90612f16565b61202933612238565b156120465760405162461bcd60e51b81526004016106ec90612f5b565b61204f33611c36565b15156001146120a05760405162461bcd60e51b815260206004820152601f60248201527f596f7520646f206e6f742068617665207374616b6564204653546f6b656e730060448201526064016106ec565b6002546120b8906001600160a01b03163330846124eb565b600354604051630f38ca0d60e31b81526001600160a01b03909116906379c65068906120ea9033908590600401612f92565b600060405180830381600087803b15801561210457600080fd5b505af1158015612118573d6000803e3d6000fd5b5050336000908152600a602052604090206001015461213a9250839150612dc2565b336000908152600a602052604081206001018290559061215990612268565b336000818152600a6020526040908190206002810184905542600490910155519192507f7d9127a72910ce617963edba28318ea738f771668f124319bd636c523b24ac0b9161084d91908590612f92565b6001600160a01b0381166000908152600a60209081526040808320815160e081018352815460ff1615158152600182810154948201949094526002820154928101929092526003810154606083015260048101546080830152600581015460a0830181905260069091015460c083015242906122299062015180612dab565b82608001516115609190612dc2565b6001600160a01b038116600090815260096020526040812054819060ff1615156001036106ba5750600192915050565b600080805b60085481101561156a576008818154811061228a5761228a612e3e565b90600052602060002090600402016002015484101580156122cf5750600881815481106122b9576122b9612e3e565b9060005260206000209060040201600301548411155b1561230057600881815481106122e7576122e7612e3e565b906000526020600020906004020160010154915061156a565b8061230a81612e54565b91505061226d565b60008061231e83612238565b156123a3576001546001600160a01b0316634551169d61233d85611f25565b6040518263ffffffff1660e01b815260040161235b91815260200190565b602060405180830381865afa158015612378573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239c9190612efd565b90506106ba565b6123ac83611c36565b156106ba576001600160a01b0383166000908152600a60205260409020600101546123d681612268565b949350505050565b60006001600160e01b03198216637965db0b60e01b14806106ba57506106ba826125e0565b61240d8282611a8e565b610ef757612425816001600160a01b03166014612615565b612430836020612615565b604051602001612441929190613060565b60408051601f198184030181529082905262461bcd60e51b82526106ec916004016130d5565b6124718282611a8e565b610ef7576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556124a73390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6040516001600160a01b03808516602483015283166044820152606481018290526125569085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526127b1565b50505050565b6125668282611a8e565b15610ef7576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b610c278363a9059cbb60e01b848460405160240161251f929190612f92565b60006001600160e01b03198216630271189760e51b14806106ba57506301ffc9a760e01b6001600160e01b03198316146106ba565b60606000612624836002612dab565b61262f906002612dc2565b67ffffffffffffffff81111561264757612647612ac8565b6040519080825280601f01601f191660200182016040528015612671576020820181803683370190505b509050600360fc1b8160008151811061268c5761268c612e3e565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106126bb576126bb612e3e565b60200101906001600160f81b031916908160001a90535060006126df846002612dab565b6126ea906001612dc2565b90505b6001811115612762576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061271e5761271e612e3e565b1a60f81b82828151811061273457612734612e3e565b60200101906001600160f81b031916908160001a90535060049490941c9361275b81613108565b90506126ed565b5083156107e35760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016106ec565b6000612806826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166128839092919063ffffffff16565b805190915015610c275780806020019051810190612824919061311f565b610c275760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016106ec565b60606107e0848460008585843b6128dc5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016106ec565b600080866001600160a01b031685876040516128f89190613141565b60006040518083038185875af1925050503d8060008114612935576040519150601f19603f3d011682016040523d82523d6000602084013e61293a565b606091505b509150915061294a828286612955565b979650505050505050565b606083156129645750816107e3565b8251156129745782518084602001fd5b8160405162461bcd60e51b81526004016106ec91906130d5565b6000602082840312156129a057600080fd5b81356001600160e01b0319811681146107e357600080fd5b6001600160a01b03811681146129cd57600080fd5b50565b6000602082840312156129e257600080fd5b81356107e3816129b8565b6000602082840312156129ff57600080fd5b5035919050565b600080600060608486031215612a1b57600080fd5b505081359360208301359350604090920135919050565b60008060408385031215612a4557600080fd5b823591506020830135612a57816129b8565b809150509250929050565b602080825282518282018190526000919060409081850190868401855b82811015612abb578151805115158552868101518786015285810151868601526060908101519085015260809093019290850190600101612a7f565b5091979650505050505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612b0757612b07612ac8565b604052919050565b600082601f830112612b2057600080fd5b8135602067ffffffffffffffff821115612b3c57612b3c612ac8565b8160051b612b4b828201612ade565b9283528481018201928281019087851115612b6557600080fd5b83870192505b8483101561294a57823582529183019190830190612b6b565b600082601f830112612b9557600080fd5b813567ffffffffffffffff811115612baf57612baf612ac8565b612bc2601f8201601f1916602001612ade565b818152846020838601011115612bd757600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a08688031215612c0c57600080fd5b8535612c17816129b8565b94506020860135612c27816129b8565b9350604086013567ffffffffffffffff80821115612c4457600080fd5b612c5089838a01612b0f565b94506060880135915080821115612c6657600080fd5b612c7289838a01612b0f565b93506080880135915080821115612c8857600080fd5b50612c9588828901612b84565b9150509295509295909350565b600080600080600060a08688031215612cba57600080fd5b8535612cc5816129b8565b94506020860135612cd5816129b8565b93506040860135925060608601359150608086013567ffffffffffffffff811115612cff57600080fd5b612c9588828901612b84565b60208082526022908201527f57616c6c6574206861732063757272656e746c79206e6f204e4654207374616b604082015261195960f21b606082015260800190565b60208082526028908201527f57616c6c657420686173207374616b656420465320546f6b656e7320616e64206040820152676e6f74204e46547360c01b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176106ba576106ba612d95565b808201808211156106ba576106ba612d95565b818103818111156106ba576106ba612d95565b6020808252818101527f4163636f756e74206973206e6f7420696e207468652061646d696e206c697374604082015260600190565b6001600160a01b039390931683526020830191909152604082015260600190565b634e487b7160e01b600052603260045260246000fd5b600060018201612e6657612e66612d95565b5060010190565b60208082526028908201527f57616c6c657420686173207374616b6564204e46547320616e64206e6f7420466040820152675320746f6b656e7360c01b606082015260800190565b60208082526028908201527f57616c6c6574206861732063757272656e746c79206e6f20465320546f6b656e6040820152671cc81cdd185ad95960c21b606082015260800190565b600060208284031215612f0f57600080fd5b5051919050565b60208082526025908201527f596f7520646f206e6f74206f776e20656e6f75676820746f6b656e7320746f206040820152647374616b6560d81b606082015260800190565b6020808252601c908201527f596f75206861766520616c7265616479207374616b6564204e46547300000000604082015260600190565b6001600160a01b03929092168252602082015260400190565b600082612fc857634e487b7160e01b600052601260045260246000fd5b500490565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a06080820181905260009082015260c00190565b6020808252601b908201527f4c6f636b757020706572696f64207374696c6c2070656e64696e670000000000604082015260600190565b60005b8381101561305757818101518382015260200161303f565b50506000910152565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161309881601785016020880161303c565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516130c981602884016020880161303c565b01602801949350505050565b60208152600082518060208401526130f481604085016020870161303c565b601f01601f19169190910160400192915050565b60008161311757613117612d95565b506000190190565b60006020828403121561313157600080fd5b815180151581146107e357600080fd5b6000825161315381846020870161303c565b919091019291505056fea264697066735822122067d4062d6fc8607b22438ab1050c07400873052d52dc01ccb20934a8a5b1e69564736f6c63430008120033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000004db1e329713f3b4d606f3d3956eed3eca7dc6e99000000000000000000000000bc0d0650412ef353d672c0bbd12efff90591b251000000000000000000000000a81b289dc053c242b43aed38f2b77e30dd459ec10000000000000000000000006e2a0a942eaa01b7eb2639b8b65d1d2768a87bac
-----Decoded View---------------
Arg [0] : _tierFactory (address): 0x4db1e329713F3b4d606f3D3956Eed3EcA7dc6E99
Arg [1] : _fsToken (address): 0xBC0d0650412EF353D672c0Bbd12eFFF90591B251
Arg [2] : _sFSToken (address): 0xa81b289dc053c242B43aed38F2B77E30dd459Ec1
Arg [3] : _devWallet (address): 0x6E2A0A942Eaa01B7EB2639B8B65D1D2768a87BAc
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000004db1e329713f3b4d606f3d3956eed3eca7dc6e99
Arg [1] : 000000000000000000000000bc0d0650412ef353d672c0bbd12efff90591b251
Arg [2] : 000000000000000000000000a81b289dc053c242b43aed38f2b77e30dd459ec1
Arg [3] : 0000000000000000000000006e2a0a942eaa01b7eb2639b8b65d1d2768a87bac
Deployed Bytecode Sourcemap
45355:25007:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45772:31;;;;;;;;;160:25:1;;;148:2;133:18;45772:31:0;;;;;;;;49065:253;;;;;;:::i;:::-;;:::i;:::-;;;652:14:1;;645:22;627:41;;615:2;600:18;49065:253:0;487:187:1;55708:938:0;;;;;;:::i;:::-;;:::i;51391:208::-;;;;;;:::i;:::-;;:::i;:::-;;51968:231;;;;;;:::i;:::-;;:::i;49433:1159::-;;;;;;:::i;:::-;;:::i;25726:123::-;;;;;;:::i;:::-;25792:7;25819:12;;;;;;;;;;:22;;;;25726:123;56756:966;;;;;;:::i;:::-;;:::i;26111:172::-;;;;;;:::i;:::-;;:::i;62734:1417::-;;;;;;:::i;:::-;;:::i;27209:280::-;;;;;;:::i;:::-;;:::i;68568:1791::-;;;:::i;61523:1053::-;;;;;;:::i;:::-;;:::i;57833:737::-;;;;;;:::i;:::-;;:::i;47098:67::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2566:14:1;;2559:22;2541:41;;2613:2;2598:18;;2591:34;;;;2641:18;;;2634:34;;;;2699:2;2684:18;;2677:34;2742:3;2727:19;;2720:35;2786:3;2771:19;;2764:35;2528:3;2513:19;47098:67:0;2260:545:1;52281:715:0;;;;;;:::i;:::-;;:::i;45892:47::-;;;;;;60293:1060;;;;;;:::i;:::-;;:::i;51685:220::-;;;;;;:::i;:::-;;:::i;45532:21::-;;;;;-1:-1:-1;;;;;45532:21:0;;;;;;-1:-1:-1;;;;;2989:32:1;;;2971:51;;2959:2;2944:18;45532:21:0;2810:218:1;46973:38:0;;;;;;:::i;:::-;;:::i;:::-;;;;3283:14:1;;3276:22;3258:41;;3330:2;3315:18;;3308:34;;;;3358:18;;;3351:34;3416:2;3401:18;;3394:34;3245:3;3230:19;46973:38:0;3033:401:1;45488:37:0;;;;;-1:-1:-1;;;;;45488:37:0;;;65867:1201;;;:::i;24586:164::-;;;;;;:::i;:::-;;:::i;53618:487::-;;;;;;:::i;:::-;;:::i;50687:158::-;;;:::i;:::-;;;;;;;:::i;45666:29::-;;;;;;22239:49;;22284:4;22239:49;;50955:351;;;;;;:::i;:::-;;:::i;59902:305::-;;;;;;:::i;:::-;;:::i;45560:22::-;;;;;-1:-1:-1;;;;;45560:22:0;;;39797:255;;;;;;:::i;:::-;-1:-1:-1;;;39797:255:0;;;;;;;;;;;-1:-1:-1;;;;;;7809:33:1;;;7791:52;;7779:2;7764:18;39797:255:0;7647:202:1;67145:1332:0;;;:::i;47172:75::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8188:14:1;;8181:22;8163:41;;8235:2;8220:18;;8213:34;;;;8263:18;;;8256:34;;;;8321:2;8306:18;;8299:34;;;;8364:3;8349:19;;8342:35;8408:3;8393:19;;8386:35;8452:3;8437:19;;8430:35;8150:3;8135:19;47172:75:0;7854:617:1;26528:174:0;;;;;;:::i;:::-;;:::i;53080:458::-;;;;;;:::i;:::-;;:::i;64227:1550::-;;;;;;:::i;:::-;;:::i;58671:756::-;;;;;;:::i;:::-;;:::i;59524:291::-;;;;;;:::i;:::-;;:::i;55087:515::-;;;;;;:::i;:::-;;:::i;54234:761::-;;;;;;:::i;:::-;;:::i;39562:227::-;;;;;;:::i;:::-;-1:-1:-1;;;39562:227:0;;;;;;;;49065:253;49244:4;49273:37;49297:12;49273:23;:37::i;:::-;49266:44;49065:253;-1:-1:-1;;49065:253:0:o;55708:938::-;55798:22;55855:36;55883:7;55855:27;:36::i;:::-;:44;;55895:4;55855:44;55833:128;;;;-1:-1:-1;;;55833:128:0;;;;;;;:::i;:::-;;;;;;;;;55994:41;56027:7;55994:32;:41::i;:::-;:50;55972:140;;;;-1:-1:-1;;;55972:140:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;56163:59:0;;56125:35;56163:59;;;:26;:59;;;;;;;;56125:97;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:35;;;56398:15;;56336:41;;56371:6;56336:41;:::i;:::-;56283:14;:32;;;:95;;;;:::i;:::-;:130;;;;:::i;:::-;56282:136;56264:349;;;56586:15;56524:14;:32;;;56559:6;56524:41;;;;:::i;:::-;56471:14;:32;;;:95;;;;:::i;:::-;:130;;;;:::i;:::-;56445:156;;56264:349;56632:6;55708:938;-1:-1:-1;;;55708:938:0:o;51391:208::-;24055:41;22284:4;683:10;24586:164;:::i;24055:41::-;24033:123;;;;-1:-1:-1;;;24033:123:0;;;;;;;:::i;:::-;51480:10:::1;::::0;;51503:18;;;;51539:52:::1;::::0;::::1;::::0;::::1;::::0;51557:10:::1;::::0;51480;;51516:5;;51539:52:::1;:::i;:::-;;;;;;;;51444:155;51391:208:::0;:::o;51968:231::-;24055:41;22284:4;683:10;24586:164;:::i;24055:41::-;24033:123;;;;-1:-1:-1;;;24033:123:0;;;;;;;:::i;:::-;52067:9:::1;::::0;;-1:-1:-1;;;;;;52089:22:0;::::1;-1:-1:-1::0;;;;;52089:22:0;;::::1;::::0;;::::1;::::0;;;52129:62:::1;::::0;;52153:10:::1;11546:34:1::0;;52067:9:0;;;::::1;11611:2:1::0;11596:18;;11589:43;;;11648:18;;;11641:43;52067:9:0;52129:62:::1;::::0;11496:2:1;11481:18;52129:62:0::1;11306:384:1::0;49433:1159:0;24055:41;22284:4;683:10;24586:164;:::i;24055:41::-;24033:123;;;;-1:-1:-1;;;24033:123:0;;;;;;;:::i;:::-;49672:16:::1;49707:18:::0;49747:9:::1;49742:233;49766:16;:23:::0;49762:27;::::1;49742:233;;;49845:7;49815:16;49832:1;49815:19;;;;;;;;:::i;:::-;;;;;;;;;;;:26;;;:37:::0;49811:153:::1;;49886:1;49873:14;;49920:4;49906:18;;49943:5;;49811:153;49791:3:::0;::::1;::::0;::::1;:::i;:::-;;;;49742:233;;;;49991:11;49987:438;;;50128:12;50085:16;50102:10;50085:28;;;;;;;;:::i;:::-;;;;;;;;;;;:40;;:55;;;;50198:12;50155:16;50172:10;50155:28;;;;;;;;:::i;:::-;;;;;;;;;;;:40;;:55;;;;49987:438;;;50343:55;::::0;;::::1;::::0;::::1;::::0;;50356:4:::1;50343:55:::0;;;::::1;::::0;::::1;::::0;;;;;;;;;;;;;;;50303:16:::1;:110:::0;;;;::::1;::::0;;-1:-1:-1;50303:110:0;;;;::::1;::::0;;::::1;::::0;;::::1;::::0;;-1:-1:-1;;50303:110:0::1;::::0;::::1;;::::0;;;::::1;::::0;;;;;;;;;;;;;;;;;;;;49987:438:::1;50442:142;::::0;;50487:10:::1;12198:51:1::0;;12280:2;12265:18;;12258:34;;;12308:18;;;12301:34;;;12366:2;12351:18;;12344:34;;;50442:142:0::1;::::0;12185:3:1;12170:19;50442:142:0::1;;;;;;;49572:1020;;49433:1159:::0;;;:::o;56756:966::-;56851:22;56908:36;56936:7;56908:27;:36::i;:::-;:45;56886:135;;;;-1:-1:-1;;;56886:135:0;;;;;;;:::i;:::-;57054:41;57087:7;57054:32;:41::i;:::-;:49;;57099:4;57054:49;57032:139;;;;-1:-1:-1;;;57032:139:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;57243:39:0;;57184:56;57243:39;;;:30;:39;;;;;;;;57184:98;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:56;;;57466:15;;57400:45;;57439:6;57400:45;:::i;:::-;57343:18;:36;;;:103;;;;:::i;:::-;:138;;;;:::i;:::-;57342:144;57324:365;;;57662:15;57596:18;:36;;;57635:6;57596:45;;;;:::i;:::-;57539:18;:36;;;:103;;;;:::i;26111:172::-;25792:7;25819:12;;;;;;;;;;:22;;;23945:30;23956:4;683:10;23945;:30::i;:::-;26250:25:::1;26261:4;26267:7;26250:10;:25::i;:::-;26111:172:::0;;;:::o;62734:1417::-;62832:7;;:29;;-1:-1:-1;;;62832:29:0;;62850:10;62832:29;;;2971:51:1;62865:21:0;;-1:-1:-1;;;;;62832:7:0;;:17;;2944:18:1;;62832:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:54;;62810:141;;;;-1:-1:-1;;;62810:141:0;;;;;;;:::i;:::-;62984:39;63012:10;62984:27;:39::i;:::-;:48;62962:126;;;;-1:-1:-1;;;62962:126:0;;;;;;;:::i;:::-;63121:44;63154:10;63121:32;:44::i;:::-;:53;63099:135;;;;-1:-1:-1;;;63099:135:0;;14569:2:1;63099:135:0;;;14551:21:1;;;14588:18;;;14581:30;14647:34;14627:18;;;14620:62;14699:18;;63099:135:0;14367:356:1;63099:135:0;63316:7;;:124;;-1:-1:-1;;;;;63316:7:0;63355:10;63388:4;63408:21;63316:24;:124::i;:::-;63481:8;;:53;;-1:-1:-1;;;63481:53:0;;-1:-1:-1;;;;;63481:8:0;;;;:18;;:53;;63500:10;;63512:21;;63481:53;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63616:15;63634:48;63660:21;63634:25;:48::i;:::-;63816:229;;;;;;;;63848:4;63816:229;;;;;;;;;;;;;;;;63925:27;;;63816:229;;;;;;63967:15;63816:229;;;;;;63997:10;;;63816:229;;;;;;64022:12;;;63816:229;;;;;;63802:10;-1:-1:-1;63771:42:0;;;:30;:42;;;;;;;:274;;;;-1:-1:-1;;63771:274:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64086:57;;63816:229;;-1:-1:-1;64086:57:0;;;;63802:10;63816:229;;64086:57;:::i;27209:280::-;-1:-1:-1;;;;;27344:23:0;;683:10;27344:23;27322:120;;;;-1:-1:-1;;;27322:120:0;;15209:2:1;27322:120:0;;;15191:21:1;15248:2;15228:18;;;15221:30;15287:34;15267:18;;;15260:62;-1:-1:-1;;;15338:18:1;;;15331:45;15393:19;;27322:120:0;15007:411:1;27322:120:0;27455:26;27467:4;27473:7;27455:11;:26::i;:::-;27209:280;;:::o;68568:1791::-;68657:44;68690:10;68657:32;:44::i;:::-;:52;;68705:4;68657:52;68635:129;;;;-1:-1:-1;;;68635:129:0;;15625:2:1;68635:129:0;;;15607:21:1;15664:2;15644:18;;;15637:30;15703:29;15683:18;;;15676:57;15750:18;;68635:129:0;15423:351:1;68635:129:0;68797:45;68831:10;68797:33;:45::i;:::-;:54;68775:129;;;;-1:-1:-1;;;68775:129:0;;15981:2:1;68775:129:0;;;15963:21:1;16020:2;16000:18;;;15993:30;16059:27;16039:18;;;16032:55;16104:18;;68775:129:0;15779:349:1;68775:129:0;69066:10;68958:56;69017:74;;;:30;:74;;;;;;;;;68958:133;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69126:8;:30;;-1:-1:-1;;;69126:30:0;;;;;2971:51:1;;;;68958:133:0;;-1:-1:-1;;;;;69126:8:0;;:18;;2944::1;;69126:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:64;;69104:146;;;;-1:-1:-1;;;69104:146:0;;16335:2:1;69104:146:0;;;16317:21:1;;;16354:18;;;16347:30;16413:34;16393:18;;;16386:62;16465:18;;69104:146:0;16133:356:1;69104:146:0;69263:33;69311:35;69575:3;69512:18;:46;;;69462:18;:30;;;:96;;;;:::i;:::-;69461:117;;;;:::i;:::-;69418:160;;69676:27;69630:18;:30;;;:73;;;;:::i;:::-;69789:7;;69589:114;;-1:-1:-1;69789:59:0;;-1:-1:-1;;;;;69789:7:0;69810:10;69589:114;69789:20;:59::i;:::-;69880:9;;69859:7;;:60;;-1:-1:-1;;;;;69859:7:0;;;;69880:9;69891:27;69859:20;:60::i;:::-;69968:8;;69998:30;;;;69968:61;;-1:-1:-1;;;69968:61:0;;-1:-1:-1;;;;;69968:8:0;;;;:17;;:61;;69986:10;;69998:30;69968:61;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;70148:10:0;70117:42;;;;:30;:42;;;;;;70110:49;;-1:-1:-1;;70110:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70200:151;;;-1:-1:-1;70200:151:0;;-1:-1:-1;70273:25:0;;70313:27;;70200:151;:::i;:::-;;;;;;;;68624:1735;;;68568:1791::o;61523:1053::-;61601:11;;:41;;-1:-1:-1;;;61601:41:0;;61645:1;;-1:-1:-1;;;;;61601:11:0;;:21;;:41;;61623:10;;61635:6;;61601:41;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:45;61579:118;;;;-1:-1:-1;;;61579:118:0;;16918:2:1;61579:118:0;;;16900:21:1;16957:2;16937:18;;;16930:30;16996:25;16976:18;;;16969:53;17039:18;;61579:118:0;16716:347:1;61579:118:0;61730:39;61758:10;61730:27;:39::i;:::-;:48;61708:126;;;;-1:-1:-1;;;61708:126:0;;;;;;;:::i;:::-;61867:44;61900:10;61867:32;:44::i;:::-;:53;61845:135;;;;-1:-1:-1;;;61845:135:0;;14569:2:1;61845:135:0;;;14551:21:1;;;14588:18;;;14581:30;14647:34;14627:18;;;14620:62;14699:18;;61845:135:0;14367:356:1;61845:135:0;62062:11;;;:70;;-1:-1:-1;;;62062:70:0;;-1:-1:-1;;;;;62062:11:0;;;;:28;;:70;;62091:10;;62111:4;;62118:6;;62062:70;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;62235:11:0;;:34;;-1:-1:-1;;;62235:34:0;;;;;160:25:1;;;62217:15:0;;-1:-1:-1;;;;;;62235:11:0;;;;-1:-1:-1;62235:26:0;;133:18:1;;62235:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;62321:168;;;;;;;;62349:4;62321:168;;;;;;;;;;;;;;;;62411:15;62321:168;;;;;;62441:10;;;62321:168;;;;;;62466:12;;;62321:168;;;;;;62307:10;-1:-1:-1;62280:38:0;;;:26;:38;;;;;;;:209;;;;-1:-1:-1;;62280:209:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62530:38;;62321:168;;-1:-1:-1;62530:38:0;;;;62307:10;62321:168;;62530:38;:::i;57833:737::-;-1:-1:-1;;;;;58075:59:0;;57925:27;58075:59;;;:26;:59;;;;;;;;58037:97;;;;;;;;;;;;;;;57979:4;58037:97;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58469:15;;58394:58;;58446:6;58394:58;:::i;:::-;58342:14;:32;;;:110;;;;:::i;:::-;:142;58324:213;;58520:5;58511:14;;58324:213;-1:-1:-1;58556:6:0;57833:737;-1:-1:-1;;57833:737:0:o;52281:715::-;24055:41;22284:4;683:10;24586:164;:::i;24055:41::-;24033:123;;;;-1:-1:-1;;;24033:123:0;;;;;;;:::i;:::-;52454:3:::1;52423:28;:34;52401:124;;;::::0;-1:-1:-1;;;52401:124:0;;17910:2:1;52401:124:0::1;::::0;::::1;17892:21:1::0;17949:2;17929:18;;;17922:30;17988:34;17968:18;;;17961:62;-1:-1:-1;;;18039:18:1;;;18032:38;18087:19;;52401:124:0::1;17708:404:1::0;52401:124:0::1;52590:1;52558:28;:33;;52536:122;;;::::0;-1:-1:-1;;;52536:122:0;;18319:2:1;52536:122:0::1;::::0;::::1;18301:21:1::0;18358:2;18338:18;;;18331:30;18397:34;18377:18;;;18370:62;-1:-1:-1;;;18448:18:1;;;18441:37;18495:19;;52536:122:0::1;18117:403:1::0;52536:122:0::1;52713:27;::::0;;52753:58;;;;52829:159:::1;::::0;::::1;::::0;::::1;::::0;52878:10:::1;::::0;52713:27;;52783:28;;52829:159:::1;:::i;60293:1060::-:0;60397:12;60444:36;60472:7;60444:27;:36::i;:::-;:44;;60484:4;60444:44;60422:126;;;;-1:-1:-1;;;60422:126:0;;18727:2:1;60422:126:0;;;18709:21:1;;;18746:18;;;18739:30;18805:34;18785:18;;;18778:62;18857:18;;60422:126:0;18525:356:1;60422:126:0;60581:37;60610:7;60581:28;:37::i;:::-;:45;;60622:4;60581:45;60559:122;;;;-1:-1:-1;;;60559:122:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;60804:59:0;;60694:11;60804:59;;;:26;:59;;;;;;;;;60766:97;;;;;;;;;;;;;;;60708:4;60766:97;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60708:4;;60766:97;61252:15;;61184:50;;61228:6;61184:50;:::i;:::-;61121:32;;;;:41;;61156:6;61121:41;:::i;:::-;61068:14;:32;;;:95;;;;:::i;:::-;:167;;;;:::i;51685:220::-;24055:41;22284:4;683:10;24586:164;:::i;24055:41::-;24033:123;;;;-1:-1:-1;;;24033:123:0;;;;;;;:::i;:::-;51778:12:::1;::::0;;51803:20;;;;51841:56:::1;::::0;::::1;::::0;::::1;::::0;51861:10:::1;::::0;51778:12;;51818:5;;51841:56:::1;:::i;46973:38::-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;46973:38:0;;;:::o;65867:1201::-;65933:39;65961:10;65933:27;:39::i;:::-;:47;;65976:4;65933:47;65911:129;;;;-1:-1:-1;;;65911:129:0;;18727:2:1;65911:129:0;;;18709:21:1;;;18746:18;;;18739:30;18805:34;18785:18;;;18778:62;18857:18;;65911:129:0;18525:356:1;65911:129:0;66073:40;66102:10;66073:28;:40::i;:::-;:48;;66117:4;66073:48;66051:125;;;;-1:-1:-1;;;66051:125:0;;;;;;;:::i;:::-;66209:52;66250:10;66209:40;:52::i;:::-;:60;;66265:4;66209:60;66187:161;;;;-1:-1:-1;;;66187:161:0;;19444:2:1;66187:161:0;;;19426:21:1;19483:2;19463:18;;;19456:30;19522:34;19502:18;;;19495:62;-1:-1:-1;;;19573:18:1;;;19566:49;19632:19;;66187:161:0;19242:415:1;66187:161:0;66481:10;66402:35;66440:62;;;:26;:62;;;;;;;;;66402:100;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66679:11;;:160;;-1:-1:-1;;;66679:160:0;;66402:100;;-1:-1:-1;;;;;66679:11:0;;;;:28;;:160;;66730:4;;66481:10;;66402:100;;66679:160;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;66950:10:0;66923:38;;;;:26;:38;;;;;;;;66916:45;;-1:-1:-1;;66916:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67039:20;;;67002:58;;;;-1:-1:-1;67002:58:0;;-1:-1:-1;67002:58:0;:::i;:::-;;;;;;;;65900:1168;65867:1201::o;24586:164::-;24689:4;24713:12;;;;;;;;;;;-1:-1:-1;;;;;24713:29:0;;;;;;;;;;;;;;;24586:164::o;53618:487::-;53703:25;53763:36;53791:7;53763:27;:36::i;:::-;:45;53741:135;;;;-1:-1:-1;;;53741:135:0;;;;;;;:::i;:::-;53909:41;53942:7;53909:32;:41::i;:::-;:49;;53954:4;53909:49;53887:139;;;;-1:-1:-1;;;53887:139:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;;54046:39:0;;;;;:30;:39;;;;;:51;;;;53618:487::o;50687:158::-;50762:34;50821:16;50814:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50687:158;:::o;50955:351::-;24055:41;22284:4;683:10;24586:164;:::i;24055:41::-;24033:123;;;;-1:-1:-1;;;24033:123:0;;;;;;;:::i;:::-;51105:11:::1;::::0;;-1:-1:-1;;;;;;51129:26:0;::::1;-1:-1:-1::0;;;;;51129:26:0;;::::1;::::0;;::::1;::::0;;;51173:125:::1;::::0;;51213:10:::1;11546:34:1::0;;51105:11:0;;;::::1;11611:2:1::0;11596:18;;11589:43;;;11648:18;;;11641:43;51105:11:0;51173:125:::1;::::0;11496:2:1;11481:18;51173:125:0::1;11306:384:1::0;59902:305:0;-1:-1:-1;;;;;60069:39:0;;59998:22;60069:39;;;:30;:39;;;;;:55;59998:22;;60069:55;;:63;;:55;:63;60065:109;;-1:-1:-1;60158:4:0;60193:6;59902:305;-1:-1:-1;;59902:305:0:o;67145:1332::-;67233:44;67266:10;67233:32;:44::i;:::-;:52;;67281:4;67233:52;67211:129;;;;-1:-1:-1;;;67211:129:0;;15625:2:1;67211:129:0;;;15607:21:1;15664:2;15644:18;;;15637:30;15703:29;15683:18;;;15676:57;15750:18;;67211:129:0;15423:351:1;67211:129:0;67373:45;67407:10;67373:33;:45::i;:::-;:53;;67422:4;67373:53;67351:130;;;;-1:-1:-1;;;67351:130:0;;;;;;;:::i;:::-;67643:10;67535:56;67594:74;;;:30;:74;;;;;;;;;67535:133;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67703:8;:30;;-1:-1:-1;;;67703:30:0;;;;;2971:51:1;;;;67535:133:0;;-1:-1:-1;;;;;67703:8:0;;:18;;2944::1;;67703:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:64;;67681:146;;;;-1:-1:-1;;;67681:146:0;;16335:2:1;67681:146:0;;;16317:21:1;;;16354:18;;;16347:30;16413:34;16393:18;;;16386:62;16465:18;;67681:146:0;16133:356:1;67681:146:0;68048:30;;;;68015:7;;:64;;-1:-1:-1;;;;;68015:7:0;;;;68036:10;;68015:20;:64::i;:::-;68128:8;;68158:30;;;;68128:61;;-1:-1:-1;;;68128:61:0;;-1:-1:-1;;;;;68128:8:0;;;;:17;;:61;;68146:10;;68158:30;68128:61;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;68308:10:0;68277:42;;;;:30;:42;;;;;;;;68270:49;;-1:-1:-1;;68270:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68428:30;;;68360:109;;;;-1:-1:-1;68360:109:0;;-1:-1:-1;68360:109:0;:::i;26528:174::-;25792:7;25819:12;;;;;;;;;;:22;;;23945:30;23956:4;683:10;23945;:30::i;:::-;26668:26:::1;26680:4;26686:7;26668:11;:26::i;53080:458::-:0;53158:19;53212:36;53240:7;53212:27;:36::i;:::-;:44;;53252:4;53212:44;53190:128;;;;-1:-1:-1;;;53190:128:0;;;;;;;:::i;:::-;53351:41;53384:7;53351:32;:41::i;:::-;:50;53329:140;;;;-1:-1:-1;;;53329:140:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;;53489:35:0;;;;;:26;:35;;;;;:41;;;;53080:458::o;64227:1550::-;64335:7;;:29;;-1:-1:-1;;;64335:29:0;;64353:10;64335:29;;;2971:51:1;64368:21:0;;-1:-1:-1;;;;;64335:7:0;;:17;;2944:18:1;;64335:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:54;;64313:141;;;;-1:-1:-1;;;64313:141:0;;;;;;;:::i;:::-;64487:39;64515:10;64487:27;:39::i;:::-;:48;64465:126;;;;-1:-1:-1;;;64465:126:0;;;;;;;:::i;:::-;64624:44;64657:10;64624:32;:44::i;:::-;:52;;64672:4;64624:52;64602:133;;;;-1:-1:-1;;;64602:133:0;;20307:2:1;64602:133:0;;;20289:21:1;20346:2;20326:18;;;20319:30;20385:33;20365:18;;;20358:61;20436:18;;64602:133:0;20105:355:1;64602:133:0;64817:7;;:124;;-1:-1:-1;;;;;64817:7:0;64856:10;64889:4;64909:21;64817:24;:124::i;:::-;64982:8;;:53;;-1:-1:-1;;;64982:53:0;;-1:-1:-1;;;;;64982:8:0;;;;:18;;:53;;65001:10;;65013:21;;64982:53;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;65225:10:0;65194:42;;;;:30;:42;;;;;:54;;;:91;;-1:-1:-1;65264:21:0;;-1:-1:-1;65194:91:0;:::i;:::-;65155:10;65124:42;;;;:30;:42;;;;;:54;;:161;;;:42;65347:105;;:25;:105::i;:::-;65494:10;65463:42;;;;:30;:42;;;;;;;:49;;;:59;;;65642:29;65579:60;;;;:92;65712:57;65329:123;;-1:-1:-1;65712:57:0;;;;65494:10;65747:21;;65712:57;:::i;58671:756::-;-1:-1:-1;;;;;58944:39:0;;58768:32;58944:39;;;:30;:39;;;;;;;;58885:98;;;;;;;;;;;;;;;58827:4;58885:98;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59326:15;;59247:62;;59303:6;59247:62;:::i;:::-;59191:18;:36;;;:118;;;;:::i;59524:291::-;-1:-1:-1;;;;;59681:35:0;;59615:17;59681:35;;;:26;:35;;;;;:51;59615:17;;59681:51;;:59;;:51;:59;59677:105;;-1:-1:-1;59766:4:0;59801:6;59524:291;-1:-1:-1;;59524:291:0:o;55087:515::-;55182:14;;;55240:329;55264:16;:23;55260:27;;55240:329;;;55348:16;55365:1;55348:19;;;;;;;;:::i;:::-;;;;;;;;;;;:31;;;55331:13;:48;;:117;;;;;55417:16;55434:1;55417:19;;;;;;;;:::i;:::-;;;;;;;;;;;:31;;;55400:13;:48;;55331:117;55309:249;;;55492:16;55509:1;55492:19;;;;;;;;:::i;:::-;;;;;;;;;;;:26;;;55483:35;;55537:5;;55309:249;55289:3;;;;:::i;:::-;;;;55240:329;;54234:761;54321:14;;54383:36;54411:7;54383:27;:36::i;:::-;54379:583;;;54537:11;;-1:-1:-1;;;;;54537:11:0;:26;54564:23;54579:7;54564:14;:23::i;:::-;54537:51;;;;;;;;;;;;;160:25:1;;148:2;133:18;;14:177;54537:51:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;54528:60;;54379:583;;;54610:41;54643:7;54610:32;:41::i;:::-;54606:356;;;-1:-1:-1;;;;;54795:71:0;;54763:29;54795:71;;;:30;:71;;;;;:83;;;54902:48;54795:83;54902:25;:48::i;:::-;54893:57;54981:6;-1:-1:-1;;;;54234:761:0:o;24248:246::-;24349:4;-1:-1:-1;;;;;;24386:47:0;;-1:-1:-1;;;24386:47:0;;:100;;;24450:36;24474:11;24450:23;:36::i;25040:497::-;25121:22;25129:4;25135:7;25121;:22::i;:::-;25116:414;;25309:41;25337:7;-1:-1:-1;;;;;25309:41:0;25347:2;25309:19;:41::i;:::-;25423:38;25451:4;25458:2;25423:19;:38::i;:::-;25214:270;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;25214:270:0;;;;;;;;;;-1:-1:-1;;;25160:358:0;;;;;;;:::i;28575:229::-;28650:22;28658:4;28664:7;28650;:22::i;:::-;28645:152;;28689:6;:12;;;;;;;;;;;-1:-1:-1;;;;;28689:29:0;;;;;;;;;:36;;-1:-1:-1;;28689:36:0;28721:4;28689:36;;;28772:12;683:10;;603:98;28772:12;-1:-1:-1;;;;;28745:40:0;28763:7;-1:-1:-1;;;;;28745:40:0;28757:4;28745:40;;;;;;;;;;28575:229;;:::o;42504:285::-;42702:68;;-1:-1:-1;;;;;22196:15:1;;;42702:68:0;;;22178:34:1;22248:15;;22228:18;;;22221:43;22280:18;;;22273:34;;;42648:133:0;;42682:5;;-1:-1:-1;;;42725:27:0;22113:18:1;;42702:68:0;;;;-1:-1:-1;;42702:68:0;;;;;;;;;;;;;;-1:-1:-1;;;;;42702:68:0;-1:-1:-1;;;;;;42702:68:0;;;;;;;;;;42648:19;:133::i;:::-;42504:285;;;;:::o;28812:230::-;28887:22;28895:4;28901:7;28887;:22::i;:::-;28883:152;;;28958:5;28926:12;;;;;;;;;;;-1:-1:-1;;;;;28926:29:0;;;;;;;;;;:37;;-1:-1:-1;;28926:37:0;;;28983:40;683:10;;28926:12;;28983:40;;28958:5;28983:40;28812:230;;:::o;42282:214::-;42365:123;42399:5;42442:23;;;42467:2;42471:5;42419:58;;;;;;;;;:::i;39198:265::-;39316:4;-1:-1:-1;;;;;;39353:49:0;;-1:-1:-1;;;39353:49:0;;:102;;-1:-1:-1;;;;;;;;;;9381:40:0;;;39419:36;9256:173;10963:476;11063:13;11089:19;11121:10;11125:6;11121:1;:10;:::i;:::-;:14;;11134:1;11121:14;:::i;:::-;11111:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;11111:25:0;;11089:47;;-1:-1:-1;;;11147:6:0;11154:1;11147:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;11147:15:0;;;;;;;;;-1:-1:-1;;;11173:6:0;11180:1;11173:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;11173:15:0;;;;;;;;-1:-1:-1;11204:9:0;11216:10;11220:6;11216:1;:10;:::i;:::-;:14;;11229:1;11216:14;:::i;:::-;11204:26;;11199:135;11236:1;11232;:5;11199:135;;;-1:-1:-1;;;11284:5:0;11292:3;11284:11;11271:25;;;;;;;:::i;:::-;;;;11259:6;11266:1;11259:9;;;;;;;;:::i;:::-;;;;:37;-1:-1:-1;;;;;11259:37:0;;;;;;;;-1:-1:-1;11321:1:0;11311:11;;;;;11239:3;;;:::i;:::-;;;11199:135;;;-1:-1:-1;11352:10:0;;11344:55;;;;-1:-1:-1;;;11344:55:0;;22661:2:1;11344:55:0;;;22643:21:1;;;22680:18;;;22673:30;22739:34;22719:18;;;22712:62;22791:18;;11344:55:0;22459:356:1;44293:802:0;44717:23;44743:106;44785:4;44743:106;;;;;;;;;;;;;;;;;44751:5;-1:-1:-1;;;;;44743:27:0;;;:106;;;;;:::i;:::-;44864:17;;44717:132;;-1:-1:-1;44864:21:0;44860:228;;44979:10;44968:30;;;;;;;;;;;;:::i;:::-;44942:134;;;;-1:-1:-1;;;44942:134:0;;23304:2:1;44942:134:0;;;23286:21:1;23343:2;23323:18;;;23316:30;23382:34;23362:18;;;23355:62;-1:-1:-1;;;23433:18:1;;;23426:40;23483:19;;44942:134:0;23102:406:1;15032:229:0;15169:12;15201:52;15223:6;15231:4;15237:1;15240:12;15169;12450:20;;16572:60;;;;-1:-1:-1;;;16572:60:0;;24122:2:1;16572:60:0;;;24104:21:1;24161:2;24141:18;;;24134:30;24200:31;24180:18;;;24173:59;24249:18;;16572:60:0;23920:353:1;16572:60:0;16646:12;16660:23;16687:6;-1:-1:-1;;;;;16687:11:0;16706:5;16727:4;16687:55;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16645:97;;;;16760:51;16777:7;16786:10;16798:12;16760:16;:51::i;:::-;16753:58;16248:571;-1:-1:-1;;;;;;;16248:571:0:o;19203:712::-;19353:12;19382:7;19378:530;;;-1:-1:-1;19413:10:0;19406:17;;19378:530;19527:17;;:21;19523:374;;19725:10;19719:17;19786:15;19773:10;19769:2;19765:19;19758:44;19523:374;19868:12;19861:20;;-1:-1:-1;;;19861:20:0;;;;;;;;:::i;196:286:1:-;254:6;307:2;295:9;286:7;282:23;278:32;275:52;;;323:1;320;313:12;275:52;349:23;;-1:-1:-1;;;;;;401:32:1;;391:43;;381:71;;448:1;445;438:12;679:131;-1:-1:-1;;;;;754:31:1;;744:42;;734:70;;800:1;797;790:12;734:70;679:131;:::o;815:247::-;874:6;927:2;915:9;906:7;902:23;898:32;895:52;;;943:1;940;933:12;895:52;982:9;969:23;1001:31;1026:5;1001:31;:::i;1067:180::-;1126:6;1179:2;1167:9;1158:7;1154:23;1150:32;1147:52;;;1195:1;1192;1185:12;1147:52;-1:-1:-1;1218:23:1;;1067:180;-1:-1:-1;1067:180:1:o;1252:316::-;1329:6;1337;1345;1398:2;1386:9;1377:7;1373:23;1369:32;1366:52;;;1414:1;1411;1404:12;1366:52;-1:-1:-1;;1437:23:1;;;1507:2;1492:18;;1479:32;;-1:-1:-1;1558:2:1;1543:18;;;1530:32;;1252:316;-1:-1:-1;1252:316:1:o;1940:315::-;2008:6;2016;2069:2;2057:9;2048:7;2044:23;2040:32;2037:52;;;2085:1;2082;2075:12;2037:52;2121:9;2108:23;2098:33;;2181:2;2170:9;2166:18;2153:32;2194:31;2219:5;2194:31;:::i;:::-;2244:5;2234:15;;;1940:315;;;;;:::o;3674:949::-;3905:2;3957:21;;;4027:13;;3930:18;;;4049:22;;;3876:4;;3905:2;4090;;4108:18;;;;4149:15;;;3876:4;4192:405;4206:6;4203:1;4200:13;4192:405;;;4265:13;;4317:9;;4310:17;4303:25;4291:38;;4369:11;;;4363:18;4349:12;;;4342:40;4422:11;;;4416:18;4402:12;;;4395:40;4458:4;4502:11;;;4496:18;4482:12;;;4475:40;4544:4;4535:14;;;;4572:15;;;;4228:1;4221:9;4192:405;;;-1:-1:-1;4614:3:1;;3674:949;-1:-1:-1;;;;;;;3674:949:1:o;4907:127::-;4968:10;4963:3;4959:20;4956:1;4949:31;4999:4;4996:1;4989:15;5023:4;5020:1;5013:15;5039:275;5110:2;5104:9;5175:2;5156:13;;-1:-1:-1;;5152:27:1;5140:40;;5210:18;5195:34;;5231:22;;;5192:62;5189:88;;;5257:18;;:::i;:::-;5293:2;5286:22;5039:275;;-1:-1:-1;5039:275:1:o;5319:712::-;5373:5;5426:3;5419:4;5411:6;5407:17;5403:27;5393:55;;5444:1;5441;5434:12;5393:55;5480:6;5467:20;5506:4;5529:18;5525:2;5522:26;5519:52;;;5551:18;;:::i;:::-;5597:2;5594:1;5590:10;5620:28;5644:2;5640;5636:11;5620:28;:::i;:::-;5682:15;;;5752;;;5748:24;;;5713:12;;;;5784:15;;;5781:35;;;5812:1;5809;5802:12;5781:35;5848:2;5840:6;5836:15;5825:26;;5860:142;5876:6;5871:3;5868:15;5860:142;;;5942:17;;5930:30;;5893:12;;;;5980;;;;5860:142;;6036:530;6078:5;6131:3;6124:4;6116:6;6112:17;6108:27;6098:55;;6149:1;6146;6139:12;6098:55;6185:6;6172:20;6211:18;6207:2;6204:26;6201:52;;;6233:18;;:::i;:::-;6277:55;6320:2;6301:13;;-1:-1:-1;;6297:27:1;6326:4;6293:38;6277:55;:::i;:::-;6357:2;6348:7;6341:19;6403:3;6396:4;6391:2;6383:6;6379:15;6375:26;6372:35;6369:55;;;6420:1;6417;6410:12;6369:55;6485:2;6478:4;6470:6;6466:17;6459:4;6450:7;6446:18;6433:55;6533:1;6508:16;;;6526:4;6504:27;6497:38;;;;6512:7;6036:530;-1:-1:-1;;;6036:530:1:o;6571:1071::-;6725:6;6733;6741;6749;6757;6810:3;6798:9;6789:7;6785:23;6781:33;6778:53;;;6827:1;6824;6817:12;6778:53;6866:9;6853:23;6885:31;6910:5;6885:31;:::i;:::-;6935:5;-1:-1:-1;6992:2:1;6977:18;;6964:32;7005:33;6964:32;7005:33;:::i;:::-;7057:7;-1:-1:-1;7115:2:1;7100:18;;7087:32;7138:18;7168:14;;;7165:34;;;7195:1;7192;7185:12;7165:34;7218:61;7271:7;7262:6;7251:9;7247:22;7218:61;:::i;:::-;7208:71;;7332:2;7321:9;7317:18;7304:32;7288:48;;7361:2;7351:8;7348:16;7345:36;;;7377:1;7374;7367:12;7345:36;7400:63;7455:7;7444:8;7433:9;7429:24;7400:63;:::i;:::-;7390:73;;7516:3;7505:9;7501:19;7488:33;7472:49;;7546:2;7536:8;7533:16;7530:36;;;7562:1;7559;7552:12;7530:36;;7585:51;7628:7;7617:8;7606:9;7602:24;7585:51;:::i;:::-;7575:61;;;6571:1071;;;;;;;;:::o;8476:734::-;8580:6;8588;8596;8604;8612;8665:3;8653:9;8644:7;8640:23;8636:33;8633:53;;;8682:1;8679;8672:12;8633:53;8721:9;8708:23;8740:31;8765:5;8740:31;:::i;:::-;8790:5;-1:-1:-1;8847:2:1;8832:18;;8819:32;8860:33;8819:32;8860:33;:::i;:::-;8912:7;-1:-1:-1;8966:2:1;8951:18;;8938:32;;-1:-1:-1;9017:2:1;9002:18;;8989:32;;-1:-1:-1;9072:3:1;9057:19;;9044:33;9100:18;9089:30;;9086:50;;;9132:1;9129;9122:12;9086:50;9155:49;9196:7;9187:6;9176:9;9172:22;9155:49;:::i;9215:398::-;9417:2;9399:21;;;9456:2;9436:18;;;9429:30;9495:34;9490:2;9475:18;;9468:62;-1:-1:-1;;;9561:2:1;9546:18;;9539:32;9603:3;9588:19;;9215:398::o;9618:404::-;9820:2;9802:21;;;9859:2;9839:18;;;9832:30;9898:34;9893:2;9878:18;;9871:62;-1:-1:-1;;;9964:2:1;9949:18;;9942:38;10012:3;9997:19;;9618:404::o;10027:127::-;10088:10;10083:3;10079:20;10076:1;10069:31;10119:4;10116:1;10109:15;10143:4;10140:1;10133:15;10159:168;10232:9;;;10263;;10280:15;;;10274:22;;10260:37;10250:71;;10301:18;;:::i;10332:125::-;10397:9;;;10418:10;;;10415:36;;;10431:18;;:::i;10462:128::-;10529:9;;;10550:11;;;10547:37;;;10564:18;;:::i;10595:356::-;10797:2;10779:21;;;10816:18;;;10809:30;10875:34;10870:2;10855:18;;10848:62;10942:2;10927:18;;10595:356::o;10956:345::-;-1:-1:-1;;;;;11176:32:1;;;;11158:51;;11240:2;11225:18;;11218:34;;;;11283:2;11268:18;;11261:34;11146:2;11131:18;;10956:345::o;11695:127::-;11756:10;11751:3;11747:20;11744:1;11737:31;11787:4;11784:1;11777:15;11811:4;11808:1;11801:15;11827:135;11866:3;11887:17;;;11884:43;;11907:18;;:::i;:::-;-1:-1:-1;11954:1:1;11943:13;;11827:135::o;12389:404::-;12591:2;12573:21;;;12630:2;12610:18;;;12603:30;12669:34;12664:2;12649:18;;12642:62;-1:-1:-1;;;12735:2:1;12720:18;;12713:38;12783:3;12768:19;;12389:404::o;12798:::-;13000:2;12982:21;;;13039:2;13019:18;;;13012:30;13078:34;13073:2;13058:18;;13051:62;-1:-1:-1;;;13144:2:1;13129:18;;13122:38;13192:3;13177:19;;12798:404::o;13415:184::-;13485:6;13538:2;13526:9;13517:7;13513:23;13509:32;13506:52;;;13554:1;13551;13544:12;13506:52;-1:-1:-1;13577:16:1;;13415:184;-1:-1:-1;13415:184:1:o;13604:401::-;13806:2;13788:21;;;13845:2;13825:18;;;13818:30;13884:34;13879:2;13864:18;;13857:62;-1:-1:-1;;;13950:2:1;13935:18;;13928:35;13995:3;13980:19;;13604:401::o;14010:352::-;14212:2;14194:21;;;14251:2;14231:18;;;14224:30;14290;14285:2;14270:18;;14263:58;14353:2;14338:18;;14010:352::o;14728:274::-;-1:-1:-1;;;;;14920:32:1;;;;14902:51;;14984:2;14969:18;;14962:34;14890:2;14875:18;;14728:274::o;16494:217::-;16534:1;16560;16550:132;;16604:10;16599:3;16595:20;16592:1;16585:31;16639:4;16636:1;16629:15;16667:4;16664:1;16657:15;16550:132;-1:-1:-1;16696:9:1;;16494:217::o;17068:635::-;-1:-1:-1;;;;;17427:15:1;;;17409:34;;17479:15;;;;17474:2;17459:18;;17452:43;17526:2;17511:18;;17504:34;17569:2;17554:18;;17547:34;;;;17389:3;17612;17597:19;;17590:32;;;17352:4;17638:19;;;17631:30;17693:3;17678:19;;17068:635::o;18886:351::-;19088:2;19070:21;;;19127:2;19107:18;;;19100:30;19166:29;19161:2;19146:18;;19139:57;19228:2;19213:18;;18886:351::o;20465:250::-;20550:1;20560:113;20574:6;20571:1;20568:13;20560:113;;;20650:11;;;20644:18;20631:11;;;20624:39;20596:2;20589:10;20560:113;;;-1:-1:-1;;20707:1:1;20689:16;;20682:27;20465:250::o;20720:812::-;21131:25;21126:3;21119:38;21101:3;21186:6;21180:13;21202:75;21270:6;21265:2;21260:3;21256:12;21249:4;21241:6;21237:17;21202:75;:::i;:::-;-1:-1:-1;;;21336:2:1;21296:16;;;21328:11;;;21321:40;21386:13;;21408:76;21386:13;21470:2;21462:11;;21455:4;21443:17;;21408:76;:::i;:::-;21504:17;21523:2;21500:26;;20720:812;-1:-1:-1;;;;20720:812:1:o;21537:396::-;21686:2;21675:9;21668:21;21649:4;21718:6;21712:13;21761:6;21756:2;21745:9;21741:18;21734:34;21777:79;21849:6;21844:2;21833:9;21829:18;21824:2;21816:6;21812:15;21777:79;:::i;:::-;21917:2;21896:15;-1:-1:-1;;21892:29:1;21877:45;;;;21924:2;21873:54;;21537:396;-1:-1:-1;;21537:396:1:o;22318:136::-;22357:3;22385:5;22375:39;;22394:18;;:::i;:::-;-1:-1:-1;;;22430:18:1;;22318:136::o;22820:277::-;22887:6;22940:2;22928:9;22919:7;22915:23;22911:32;22908:52;;;22956:1;22953;22946:12;22908:52;22988:9;22982:16;23041:5;23034:13;23027:21;23020:5;23017:32;23007:60;;23063:1;23060;23053:12;24278:287;24407:3;24445:6;24439:13;24461:66;24520:6;24515:3;24508:4;24500:6;24496:17;24461:66;:::i;:::-;24543:16;;;;;24278:287;-1:-1:-1;;24278:287:1:o
Swarm Source
ipfs://67d4062d6fc8607b22438ab1050c07400873052d52dc01ccb20934a8a5b1e695
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.