Overview
ETH Balance
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 9 from a total of 9 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Transfer Ownersh... | 43561595 | 787 days ago | IN | 0 ETH | 0.000052328959 | ||||
Transfer From | 43561509 | 787 days ago | IN | 0 ETH | 0.000059040486 | ||||
Set Admin | 43561413 | 787 days ago | IN | 0 ETH | 0.000052330504 | ||||
Set Ref | 43561306 | 787 days ago | IN | 0 ETH | 0.000052330482 | ||||
Set Interest Rat... | 43561213 | 787 days ago | IN | 0 ETH | 0.000049444172 | ||||
Set Gain Ratio | 43561132 | 787 days ago | IN | 0 ETH | 0.000049747747 | ||||
Set Fees | 43561047 | 787 days ago | IN | 0 ETH | 0.000046542402 | ||||
Set Max Debt | 43561024 | 787 days ago | IN | 0 ETH | 0.000045238163 | ||||
Set Max Debt | 43561004 | 787 days ago | IN | 0 ETH | 0.00004496716 |
View more zero value Internal Transactions in Advanced View mode
Contract Source Code (Solidity)
/** *Submitted for verification at optimistic.etherscan.io on 2022-11-29 */ // Sources flattened with hardhat v2.12.2 https://hardhat.org // File contracts/interfaces/external/IPriceSourceAll.sol pragma solidity 0.8.11; interface IPriceSource { function latestRoundData() external view returns (uint256); function latestAnswer() external view returns (uint256); function decimals() external view returns (uint8); } // File @openzeppelin/contracts/utils/[email protected] // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @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 * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 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 functionCallWithValue(target, data, 0, "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"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or 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 { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // 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 /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } // File @openzeppelin/contracts/utils/introspection/[email protected] // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @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); } // File @openzeppelin/contracts/token/ERC721/[email protected] // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); } // File @openzeppelin/contracts/utils/[email protected] // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with 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; } } // File @openzeppelin/contracts/token/ERC721/[email protected] // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } // File @openzeppelin/contracts/token/ERC721/extensions/[email protected] // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); } // File @openzeppelin/contracts/utils/math/[email protected] // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10**64) { value /= 10**64; result += 64; } if (value >= 10**32) { value /= 10**32; result += 32; } if (value >= 10**16) { value /= 10**16; result += 16; } if (value >= 10**8) { value /= 10**8; result += 8; } if (value >= 10**4) { value /= 10**4; result += 4; } if (value >= 10**2) { value /= 10**2; result += 2; } if (value >= 10**1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0); } } } // File @openzeppelin/contracts/utils/[email protected] // OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @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] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } } // File @openzeppelin/contracts/utils/introspection/[email protected] // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; /** * @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; } } // File @openzeppelin/contracts/token/ERC721/[email protected] // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/ERC721.sol) pragma solidity ^0.8.0; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { using Address for address; using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: address zero is not a valid owner"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _ownerOf(tokenId); require(owner != address(0), "ERC721: invalid token ID"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { _requireMinted(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not token owner or approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { _requireMinted(tokenId); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom( address from, address to, uint256 tokenId ) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory data ) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _safeTransfer(from, to, tokenId, data); } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * `data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer( address from, address to, uint256 tokenId, bytes memory data ) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist */ function _ownerOf(uint256 tokenId) internal view virtual returns (address) { return _owners[tokenId]; } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _ownerOf(tokenId) != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { address owner = ERC721.ownerOf(tokenId); return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint( address to, uint256 tokenId, bytes memory data ) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId, 1); // Check that tokenId was not minted by `_beforeTokenTransfer` hook require(!_exists(tokenId), "ERC721: token already minted"); unchecked { // Will not overflow unless all 2**256 token ids are minted to the same owner. // Given that tokens are minted one by one, it is impossible in practice that // this ever happens. Might change if we allow batch minting. // The ERC fails to describe this case. _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); _afterTokenTransfer(address(0), to, tokenId, 1); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * This is an internal function that does not check if the sender is authorized to operate on the token. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId, 1); // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook owner = ERC721.ownerOf(tokenId); // Clear approvals delete _tokenApprovals[tokenId]; unchecked { // Cannot overflow, as that would require more tokens to be burned/transferred // out than the owner initially received through minting and transferring in. _balances[owner] -= 1; } delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); _afterTokenTransfer(owner, address(0), tokenId, 1); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer( address from, address to, uint256 tokenId ) internal virtual { require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId, 1); // Check that tokenId was not transferred by `_beforeTokenTransfer` hook require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); // Clear approvals from the previous owner delete _tokenApprovals[tokenId]; unchecked { // `_balances[from]` cannot overflow for the same reason as described in `_burn`: // `from`'s balance is the number of token held, which is at least one before the current // transfer. // `_balances[to]` could overflow in the conditions described in `_mint`. That would require // all 2**256 token ids to be minted, which in practice is impossible. _balances[from] -= 1; _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(from, to, tokenId); _afterTokenTransfer(from, to, tokenId, 1); } /** * @dev Approve `to` to operate on `tokenId` * * Emits an {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll( address owner, address operator, bool approved ) internal virtual { require(owner != operator, "ERC721: approve to caller"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Reverts if the `tokenId` has not been minted yet. */ function _requireMinted(uint256 tokenId) internal view virtual { require(_exists(tokenId), "ERC721: invalid token ID"); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory data ) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721: transfer to non ERC721Receiver implementer"); } else { /// @solidity memory-safe-assembly assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`. * - When `from` is zero, the tokens will be minted for `to`. * - When `to` is zero, ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256, /* firstTokenId */ uint256 batchSize ) internal virtual { if (batchSize > 1) { if (from != address(0)) { _balances[from] -= batchSize; } if (to != address(0)) { _balances[to] += batchSize; } } } /** * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`. * - When `from` is zero, the tokens were minted for `to`. * - When `to` is zero, ``from``'s tokens were burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize ) internal virtual {} } // File @openzeppelin/contracts/token/ERC721/extensions/[email protected] // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol) pragma solidity ^0.8.0; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); } // File @openzeppelin/contracts/token/ERC721/extensions/[email protected] // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/extensions/ERC721Enumerable.sol) pragma solidity ^0.8.0; /** * @dev This implements an optional extension of {ERC721} defined in the EIP that adds * enumerability of all the token ids in the contract as well as all token ids owned by each * account. */ abstract contract ERC721Enumerable is ERC721, IERC721Enumerable { // Mapping from owner to list of owned token IDs mapping(address => mapping(uint256 => uint256)) private _ownedTokens; // Mapping from token ID to index of the owner tokens list mapping(uint256 => uint256) private _ownedTokensIndex; // Array with all token ids, used for enumeration uint256[] private _allTokens; // Mapping from token id to position in the allTokens array mapping(uint256 => uint256) private _allTokensIndex; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) { return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) { require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds"); return _ownedTokens[owner][index]; } /** * @dev See {IERC721Enumerable-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _allTokens.length; } /** * @dev See {IERC721Enumerable-tokenByIndex}. */ function tokenByIndex(uint256 index) public view virtual override returns (uint256) { require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds"); return _allTokens[index]; } /** * @dev See {ERC721-_beforeTokenTransfer}. */ function _beforeTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize ) internal virtual override { super._beforeTokenTransfer(from, to, firstTokenId, batchSize); if (batchSize > 1) { // Will only trigger during construction. Batch transferring (minting) is not available afterwards. revert("ERC721Enumerable: consecutive transfers not supported"); } uint256 tokenId = firstTokenId; if (from == address(0)) { _addTokenToAllTokensEnumeration(tokenId); } else if (from != to) { _removeTokenFromOwnerEnumeration(from, tokenId); } if (to == address(0)) { _removeTokenFromAllTokensEnumeration(tokenId); } else if (to != from) { _addTokenToOwnerEnumeration(to, tokenId); } } /** * @dev Private function to add a token to this extension's ownership-tracking data structures. * @param to address representing the new owner of the given token ID * @param tokenId uint256 ID of the token to be added to the tokens list of the given address */ function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private { uint256 length = ERC721.balanceOf(to); _ownedTokens[to][length] = tokenId; _ownedTokensIndex[tokenId] = length; } /** * @dev Private function to add a token to this extension's token tracking data structures. * @param tokenId uint256 ID of the token to be added to the tokens list */ function _addTokenToAllTokensEnumeration(uint256 tokenId) private { _allTokensIndex[tokenId] = _allTokens.length; _allTokens.push(tokenId); } /** * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for * gas optimizations e.g. when performing a transfer operation (avoiding double writes). * This has O(1) time complexity, but alters the order of the _ownedTokens array. * @param from address representing the previous owner of the given token ID * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address */ function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private { // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = ERC721.balanceOf(from) - 1; uint256 tokenIndex = _ownedTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary if (tokenIndex != lastTokenIndex) { uint256 lastTokenId = _ownedTokens[from][lastTokenIndex]; _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index } // This also deletes the contents at the last position of the array delete _ownedTokensIndex[tokenId]; delete _ownedTokens[from][lastTokenIndex]; } /** * @dev Private function to remove a token from this extension's token tracking data structures. * This has O(1) time complexity, but alters the order of the _allTokens array. * @param tokenId uint256 ID of the token to be removed from the tokens list */ function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private { // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = _allTokens.length - 1; uint256 tokenIndex = _allTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding // an 'if' statement (like in _removeTokenFromOwnerEnumeration) uint256 lastTokenId = _allTokens[lastTokenIndex]; _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index // This also deletes the contents at the last position of the array delete _allTokensIndex[tokenId]; _allTokens.pop(); } } // File contracts/token/ERC721/MyVaultV4.sol // contracts/MyVaultNFT.sol pragma solidity 0.8.11; contract VaultNFTv4 is ERC721, ERC721Enumerable { string public uri; function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) internal override(ERC721, ERC721Enumerable) { super._beforeTokenTransfer(from, to, tokenId, batchSize); } function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC721Enumerable) returns (bool) { return super.supportsInterface(interfaceId); } constructor(string memory name, string memory symbol, string memory _uri) ERC721(name, symbol) { uri = _uri; } function tokenURI(uint256 tokenId) public override view returns (string memory) { require(_exists(tokenId)); return uri; } } // File @openzeppelin/contracts/security/[email protected] // OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } } // File @openzeppelin/contracts/token/ERC20/[email protected] // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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 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 `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount ) external returns (bool); } // File @openzeppelin/contracts/token/ERC20/extensions/[email protected] // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } // File @openzeppelin/contracts/token/ERC20/[email protected] // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address to, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _transfer(owner, to, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _approve(owner, spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. * - the caller must have allowance for ``from``'s tokens of at least * `amount`. */ function transferFrom( address from, address to, uint256 amount ) public virtual override returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, amount); _transfer(from, to, amount); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, allowance(owner, spender) + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { address owner = _msgSender(); uint256 currentAllowance = allowance(owner, spender); require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(owner, spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `from` to `to`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. */ function _transfer( address from, address to, uint256 amount ) internal virtual { require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(from, to, amount); uint256 fromBalance = _balances[from]; require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[from] = fromBalance - amount; // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by // decrementing then incrementing. _balances[to] += amount; } emit Transfer(from, to, amount); _afterTokenTransfer(from, to, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; unchecked { // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above. _balances[account] += amount; } emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; // Overflow not possible: amount <= accountBalance <= totalSupply. _totalSupply -= amount; } emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Updates `owner` s allowance for `spender` based on spent `amount`. * * Does not update the allowance amount in case of infinite allowance. * Revert if not enough allowance is available. * * Might emit an {Approval} event. */ function _spendAllowance( address owner, address spender, uint256 amount ) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { require(currentAllowance >= amount, "ERC20: insufficient allowance"); unchecked { _approve(owner, spender, currentAllowance - amount); } } } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} } // File @openzeppelin/contracts/token/ERC20/extensions/[email protected] // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); } // File @openzeppelin/contracts/token/ERC20/utils/[email protected] // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + 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)); } } function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @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"); } } } // File contracts/fixedInterestVaults/fixedVault.sol pragma solidity 0.8.11; contract fixedVault is ReentrancyGuard, VaultNFTv4 { using SafeERC20 for ERC20; /// @dev Constants used across the contract. uint256 constant TEN_THOUSAND = 10000; uint256 constant ONE_YEAR = 31556952; uint256 constant THOUSAND = 1000; IPriceSource public ethPriceSource; uint256 public _minimumCollateralPercentage; uint256 public vaultCount; uint256 public closingFee; uint256 public openingFee; uint256 public minDebt; uint256 public maxDebt; uint256 constant public tokenPeg = 1e8; // $1 uint256 public iR; mapping(uint256 => uint256) public vaultCollateral; mapping(uint256 => uint256) public accumulatedVaultDebt; mapping(uint256 => uint256) public lastInterest; mapping(uint256 => uint256) public promoter; uint256 public adminFee; // 10% of the earned interest uint256 public refFee; // 90% of the earned interest uint256 public debtRatio; uint256 public gainRatio; ERC20 public collateral; ERC20 public mai; uint256 public decimalDifferenceRaisedToTen; uint256 public priceSourceDecimals; uint256 public totalBorrowed; mapping(address => uint256) public maticDebt; uint256 public maiDebt; address public stabilityPool; address public adm; address public ref; address public router; uint8 public version = 7; event CreateVault(uint256 vaultID, address creator); event DestroyVault(uint256 vaultID); event DepositCollateral(uint256 vaultID, uint256 amount); event WithdrawCollateral(uint256 vaultID, uint256 amount); event BorrowToken(uint256 vaultID, uint256 amount); event PayBackToken(uint256 vaultID, uint256 amount, uint256 closingFee); event LiquidateVault( uint256 vaultID, address owner, address buyer, uint256 debtRepaid, uint256 collateralLiquidated, uint256 closingFee ); event BoughtRiskyDebtVault(uint256 riskyVault, uint256 newVault, address riskyVaultBuyer, uint256 amountPaidtoBuy); constructor( address ethPriceSourceAddress, uint256 minimumCollateralPercentage, string memory name, string memory symbol, address _mai, address _collateral, string memory baseURI ) VaultNFTv4(name, symbol, baseURI) { require(ethPriceSourceAddress != address(0)); require(minimumCollateralPercentage != 0); closingFee = 50; // 0.5% openingFee = 0; // 0.0% ethPriceSource = IPriceSource(ethPriceSourceAddress); stabilityPool = address(0); maxDebt = 500000 ether; //Keeping maxDebt at 500K * 10^(18) debtRatio = 2; // 1/2, pay back 50% gainRatio = 1100; // /10 so 1.1 _minimumCollateralPercentage = minimumCollateralPercentage; collateral = ERC20(_collateral); mai = ERC20(_mai); priceSourceDecimals = 8; /* This works only for collaterals with decimals < 18 */ decimalDifferenceRaisedToTen = 10**(mai.decimals() - collateral.decimals()); adm = msg.sender; ref = msg.sender; } modifier onlyVaultOwner(uint256 vaultID) { require(_exists(vaultID), "Vault does not exist"); require(ownerOf(vaultID) == msg.sender, "Vault is not owned by you"); _; } modifier onlyRouter() { require( router == address(0) || msg.sender == router, "must use router" ); _; } modifier vaultExists(uint256 vaultID) { require(_exists(vaultID), "Vault does not exist"); _; } modifier frontExists(uint256 vaultID) { require(_exists(vaultID), "front end vault does not exist"); require(promoter[vaultID] <= TEN_THOUSAND && promoter[vaultID] > 0, "Front end not added"); _; } /// @notice Return the current debt available to borrow. /// @dev checks the outstanding balance of the borrowable asset within the contract. /// @return available balance of borrowable asset. function getDebtCeiling() public view returns (uint256) { return mai.balanceOf(address(this)); } /// @param vaultID is the token id of the vault being checked. /// @notice Returns true if a vault exists /// @dev the erc721 spec allows users to burn/destroy their nft /// @return boolean if the vault exists function exists(uint256 vaultID) external view returns (bool) { return _exists(vaultID); } /// @notice Returns the total value locked in the vault, based on the oracle price. /// @return uint256 total value locked in vault function getTotalValueLocked() external view returns (uint256) { return ( getEthPriceSource() * decimalDifferenceRaisedToTen * collateral.balanceOf(address(this)) ) ; //extra 1e8, to get fraction in ui // 1e8 * 1eDelta } /// @notice Return the fee charged when repaying a vault. /// @return uint256 is the fee charged to a vault when repaying. function getClosingFee() external view returns (uint256) { return closingFee; } /// @notice Return the peg maintained by the vault. /// @return uint256 is the value with 8 decimals used to calculate borrowable debt. function getTokenPriceSource() public view returns (uint256) { return tokenPeg; } /// @notice Return the collateral value /// @return uint256 is the value retrieved from the oracle used /// to calculate the available borrowable amounts. function getEthPriceSource() public view returns (uint256) { return ethPriceSource.latestAnswer(); } /// @param vaultID is the token id of the vault being checked. /// @notice Returns the debt owned by the vault and the interest accrued over time. /// @return uint256 fee earned in the time between updates /// @return uint256 debt owed by the vault for further calculation. function _vaultDebtAndFee(uint256 vaultID) internal view returns (uint256, uint256) { uint256 currentTime = block.timestamp; uint256 debt = accumulatedVaultDebt[vaultID]; uint256 fee = 0; if (lastInterest[vaultID] != 0 && iR > 0) { uint256 timeDelta = currentTime - lastInterest[vaultID]; uint256 feeAccrued = (((iR * debt) * timeDelta) / ONE_YEAR) / TEN_THOUSAND; fee = feeAccrued; debt = feeAccrued + debt; } return (fee, debt); } /// @param vaultID is the token id of the vault being checked. /// @notice Returns the debt owned by the vault without tracking the interest /// @return uint256 debt owed by the vault for further calculation. function vaultDebt(uint256 vaultID) public view returns (uint256) { (, uint256 debt) = _vaultDebtAndFee(vaultID); return debt; } /// @param vaultID is the token id of the vault being checked. /// @notice Adds the interest charged to the vault over the previous time called. /// @return uint256 latest vault debt function updateVaultDebt(uint256 vaultID) public returns (uint256) { (uint256 fee, uint256 debt) = _vaultDebtAndFee(vaultID); maiDebt = maiDebt + fee; totalBorrowed = totalBorrowed + fee; if(iR > 0) { lastInterest[vaultID] = block.timestamp; } // we can just update the current vault debt here instead accumulatedVaultDebt[vaultID] = debt; return debt; } /// @param _collateral is the amount of collateral tokens to be valued. /// @param _debt is the debt owed by the vault. /// @notice Returns collateral value and debt based on the oracle prices /// @return uint256 coolateral value * 100. used to calculate the CDR /// @return uint256 debt value. Uses token price source to derive. function calculateCollateralProperties(uint256 _collateral, uint256 _debt) private view returns (uint256, uint256) { require(getEthPriceSource() != 0); require(getTokenPriceSource() != 0); uint256 collateralValue = _collateral * getEthPriceSource() * decimalDifferenceRaisedToTen; require(collateralValue >= _collateral); uint256 debtValue = _debt * getTokenPriceSource(); require(debtValue >= _debt); uint256 collateralValueTimes100 = collateralValue * 100; require(collateralValueTimes100 > collateralValue); return (collateralValueTimes100, debtValue); } /// @param _collateral is the amount of collateral tokens held by vault. /// @param debt is the debt owed by the vault. /// @notice Calculates if the CDR is valid before taking a further action with a user /// @return boolean describing if the new CDR is valid. function isValidCollateral(uint256 _collateral, uint256 debt) public view returns (bool) { ( uint256 collateralValueTimes100, uint256 debtValue ) = calculateCollateralProperties(_collateral, debt); uint256 collateralPercentage = collateralValueTimes100 / debtValue; return collateralPercentage >= _minimumCollateralPercentage; } /// @param fee is the amount of basis points (BP) to charge /// @param amount is the total value to calculate the BPs from /// @param promoFee is the fee charged by the front end /// @notice Returns fee to charge based on the collateral amount /// @return uint256 fee to charge the collateral. /// @dev fee can be called on web app to compare charges. function calculateFee( uint256 fee, uint256 amount, uint256 promoFee ) public view returns (uint256) { uint256 _fee; if (promoFee>0) { _fee = ((amount * fee * getTokenPriceSource() * promoFee) / (getEthPriceSource() * TEN_THOUSAND * TEN_THOUSAND)); } else { _fee = (amount * fee * getTokenPriceSource()) / (getEthPriceSource() * TEN_THOUSAND); } return _fee / decimalDifferenceRaisedToTen; } /// @notice Creates a new ERC721 Vault NFT /// @return uint256 the token id of the vault created. function createVault() public returns (uint256) { uint256 id = vaultCount; vaultCount = vaultCount + 1; require(vaultCount >= id); _mint(msg.sender, id); emit CreateVault(id, msg.sender); return id; } /// @notice Destroys an ERC721 Vault NFT /// @param vaultID the vault ID to destroy /// @dev vault must not have any debt owed to be able to be destroyed. function destroyVault(uint256 vaultID) external onlyVaultOwner(vaultID) nonReentrant { require(vaultDebt(vaultID) == 0, "Vault has outstanding debt"); if (vaultCollateral[vaultID] != 0) { // withdraw leftover collateral collateral.safeTransfer(ownerOf(vaultID), vaultCollateral[vaultID]); } _burn(vaultID); delete vaultCollateral[vaultID]; delete accumulatedVaultDebt[vaultID]; delete lastInterest[vaultID]; emit DestroyVault(vaultID); } /// @param vaultID is the token id of the vault being interacted with. /// @param amount is the amount of collateral to deposit from msg.sender /// @notice Adds collateral to a specific vault by token id /// @dev Any address can deposit into a vault function depositCollateral(uint256 vaultID, uint256 amount) external vaultExists(vaultID) onlyRouter { uint256 newCollateral = vaultCollateral[vaultID] + (amount); require(newCollateral >= vaultCollateral[vaultID]); vaultCollateral[vaultID] = newCollateral; collateral.safeTransferFrom(msg.sender, address(this), amount); emit DepositCollateral(vaultID, amount); } /// @param vaultID is the token id of the vault being interacted with. /// @param amount is the amount of collateral to withdraw /// @notice withdraws collateral to a specific vault by token id /// @dev If there is debt, then it can only withdraw up to the min CDR. function withdrawCollateral(uint256 vaultID, uint256 amount) external onlyVaultOwner(vaultID) nonReentrant { require( vaultCollateral[vaultID] >= amount, "Vault does not have enough collateral" ); uint256 newCollateral = vaultCollateral[vaultID] - amount; uint256 debt = updateVaultDebt(vaultID); if (debt != 0) { require( isValidCollateral(newCollateral, debt), "Withdrawal would put vault below minimum collateral percentage" ); } vaultCollateral[vaultID] = newCollateral; collateral.safeTransfer(msg.sender, amount); emit WithdrawCollateral(vaultID, amount); } /// @param vaultID is the token id of the vault being interacted with. /// @param amount is the amount of borrowable asset to borrow /// @notice borrows asset based on the collateral held and the price of the collateral. /// @dev Borrowing is limited by the CDR of the vault /// If there's opening fee, it will be charged here. function borrowToken( uint256 vaultID, uint256 amount, uint256 _front ) external frontExists(_front) onlyVaultOwner(vaultID) nonReentrant { require(amount > 0, "Must borrow non-zero amount"); require( amount <= getDebtCeiling(), "borrowToken: Cannot mint over available supply." ); uint256 newDebt = updateVaultDebt(vaultID) + amount; require(newDebt<=maxDebt, "borrowToken: max loan cap reached."); require(newDebt > vaultDebt(vaultID)); require( isValidCollateral(vaultCollateral[vaultID], newDebt), "Borrow would put vault below minimum collateral percentage" ); require( ((vaultDebt(vaultID)) + amount) >= minDebt, "Vault debt can't be under minDebt" ); accumulatedVaultDebt[vaultID] = newDebt; uint256 _openingFee = calculateFee(openingFee, newDebt, promoter[_front]); vaultCollateral[vaultID] = vaultCollateral[vaultID] - (_openingFee); vaultCollateral[_front] = vaultCollateral[_front] + (_openingFee); // mai mai.safeTransfer(msg.sender, amount); totalBorrowed = totalBorrowed + (amount); emit BorrowToken(vaultID, amount); } function paybackTokenAll( uint256 vaultID, uint256 deadline, uint256 _front ) external frontExists(_front) vaultExists(vaultID) onlyRouter { require( deadline >= block.timestamp, "paybackTokenAll: deadline expired." ); uint256 _amount = updateVaultDebt(vaultID); payBackToken(vaultID, _amount, _front); } /// @param vaultID is the token id of the vault being interacted with. /// @param amount is the amount of borrowable asset to repay /// @param _front is the front end that will get the opening /// @notice payback asset to close loan. /// @dev If there is debt, then it can only withdraw up to the min CDR. function payBackToken( uint256 vaultID, uint256 amount, uint256 _front ) public frontExists(_front) vaultExists(vaultID) onlyRouter { require(mai.balanceOf(msg.sender) >= amount, "Token balance too low"); uint256 vaultDebtNow = updateVaultDebt(vaultID); require( vaultDebtNow >= amount, "Vault debt less than amount to pay back" ); require( ((vaultDebtNow) - amount) >= minDebt || amount == (vaultDebtNow), "Vault debt can't be under minDebt" ); uint256 _closingFee = calculateFee( closingFee, amount, promoter[_front] ); accumulatedVaultDebt[vaultID] = vaultDebtNow - amount; vaultCollateral[vaultID] = vaultCollateral[vaultID] - _closingFee; vaultCollateral[_front] = vaultCollateral[_front] + _closingFee; totalBorrowed = totalBorrowed - amount; //mai mai.safeTransferFrom(msg.sender, address(this), amount); emit PayBackToken(vaultID, amount, _closingFee); } /// @notice withdraws liquidator earnings. /// @dev reverts if there's no collateral to withdraw. function getPaid() external nonReentrant { require(maticDebt[msg.sender] != 0, "Don't have anything for you."); uint256 amount = maticDebt[msg.sender]; maticDebt[msg.sender] = 0; collateral.safeTransfer(msg.sender, amount); } /// @param pay is address of the person to getPaid /// @notice withdraws liquidator earnings. /// @dev reverts if there's no collateral to withdraw. function getPaid(address pay) external nonReentrant { require(maticDebt[pay] != 0, "Don't have anything for you."); uint256 amount = maticDebt[pay]; maticDebt[pay] = 0; collateral.safeTransfer(pay, amount); } /// @param vaultID is the token id of the vault being interacted with. /// @notice Calculates cost to liquidate a vault /// @dev Can be used to calculate balance required to liquidate a vault. function checkCost(uint256 vaultID) public view returns (uint256) { uint256 vaultDebtNow = vaultDebt(vaultID); if ( vaultCollateral[vaultID] == 0 || vaultDebtNow == 0 || !checkLiquidation(vaultID) ) { return 0; } (, uint256 debtValue ) = calculateCollateralProperties( vaultCollateral[vaultID], vaultDebtNow ); if (debtValue == 0) { return 0; } debtValue = debtValue / (10**priceSourceDecimals); uint256 halfDebt = debtValue / debtRatio; //debtRatio (2) if (halfDebt <= minDebt) { halfDebt = debtValue; } return (halfDebt); } /// @param vaultID is the token id of the vault being interacted with. /// @notice Calculates collateral to extract when liquidating a vault /// @dev Can be used to calculate earnings from liquidating a vault. function checkExtract(uint256 vaultID) public view returns (uint256) { if (vaultCollateral[vaultID] == 0 || !checkLiquidation(vaultID)) { return 0; } uint256 vaultDebtNow = vaultDebt(vaultID); (, uint256 debtValue) = calculateCollateralProperties( vaultCollateral[vaultID], vaultDebtNow ); uint256 halfDebt = debtValue / debtRatio; //debtRatio (2) if (halfDebt == 0) { return 0; } if ((halfDebt) / (10**priceSourceDecimals) <= minDebt) { // full liquidation if under the min debt. return (debtValue * ( gainRatio)) / (THOUSAND) / (getEthPriceSource()) / decimalDifferenceRaisedToTen; } else { return (halfDebt * (gainRatio)) / THOUSAND / (getEthPriceSource()) / decimalDifferenceRaisedToTen; } } /// @param vaultID is the token id of the vault being interacted with. /// @notice Calculates the collateral percentage of a vault. function checkCollateralPercentage(uint256 vaultID) public view vaultExists(vaultID) returns (uint256) { uint256 vaultDebtNow = vaultDebt(vaultID); if (vaultCollateral[vaultID] == 0 || vaultDebtNow == 0) { return 0; } ( uint256 collateralValueTimes100, uint256 debtValue ) = calculateCollateralProperties( vaultCollateral[vaultID], vaultDebtNow ); return collateralValueTimes100 / (debtValue); } /// @param vaultID is the token id of the vault being interacted with. /// @notice Calculates if a vault is liquidatable. /// @return bool if vault is liquidatable or not. function checkLiquidation(uint256 vaultID) public view vaultExists(vaultID) returns (bool) { uint256 vaultDebtNow = vaultDebt(vaultID); if (vaultCollateral[vaultID] == 0 || vaultDebtNow == 0) { return false; } ( uint256 collateralValueTimes100, uint256 debtValue ) = calculateCollateralProperties( vaultCollateral[vaultID], vaultDebtNow ); uint256 collateralPercentage = collateralValueTimes100 / (debtValue); if (collateralPercentage < _minimumCollateralPercentage) { return true; } else { return false; } } /// @param vaultID is the token id of the vault being interacted with. /// @notice Calculates if a vault is risky and can be bought. /// @return bool if vault is risky or not. function checkRiskyVault(uint256 vaultID) public view vaultExists(vaultID) returns (bool) { uint256 vaultDebtNow = vaultDebt(vaultID); if (vaultCollateral[vaultID] == 0 || vaultDebtNow == 0) { return false; } ( uint256 collateralValueTimes100, uint256 debtValue ) = calculateCollateralProperties( vaultCollateral[vaultID], vaultDebtNow ); uint256 collateralPercentage = collateralValueTimes100 / (debtValue); if ((collateralPercentage*10) <= gainRatio) { return true; } else { return false; } } /// @param vaultID is the token id of the vault being interacted with. /// @notice Pays back the part of the debt owed by the vault and removes a /// comparable amount of collateral plus bonus /// @dev if vault CDR is under the bonus ratio, /// then it will only be able to be bought through buy risky. /// Amount to pay back is based on debtRatio variable. function liquidateVault(uint256 vaultID, uint256 _front) external frontExists(_front) vaultExists(vaultID) { require( stabilityPool == address(0) || msg.sender == stabilityPool, "liquidation is disabled for public" ); uint256 vaultDebtNow = updateVaultDebt(vaultID); ( uint256 collateralValueTimes100, uint256 debtValue ) = calculateCollateralProperties( vaultCollateral[vaultID], vaultDebtNow ); require(vaultDebtNow != 0, "Vault debt is 0"); uint256 collateralPercentage = collateralValueTimes100 / (debtValue); require( collateralPercentage < _minimumCollateralPercentage, "Vault is not below minimum collateral percentage" ); require(collateralPercentage * 10 > gainRatio , "Vault is not above gain ratio"); debtValue = debtValue / (10**priceSourceDecimals); uint256 halfDebt = debtValue / (debtRatio); //debtRatio (2) if (halfDebt <= minDebt) { halfDebt = debtValue; } require( mai.balanceOf(msg.sender) >= halfDebt, "Token balance too low to pay off outstanding debt" ); totalBorrowed = totalBorrowed - (halfDebt); uint256 maticExtract = checkExtract(vaultID); accumulatedVaultDebt[vaultID] = vaultDebtNow - (halfDebt); // we paid back half of its debt. uint256 _closingFee = calculateFee(closingFee, halfDebt, promoter[_front]); vaultCollateral[vaultID] = vaultCollateral[vaultID] - (_closingFee); vaultCollateral[_front] = vaultCollateral[_front] + (_closingFee); // deduct the amount from the vault's collateral vaultCollateral[vaultID] = vaultCollateral[vaultID] - (maticExtract); // let liquidator take the collateral maticDebt[msg.sender] = maticDebt[msg.sender] + (maticExtract); //mai mai.safeTransferFrom(msg.sender, address(this), halfDebt); emit LiquidateVault( vaultID, ownerOf(vaultID), msg.sender, halfDebt, maticExtract, _closingFee ); } /// @param vaultID is the token id of the vault being interacted with. /// @notice Pays back the debt owed to bring it back to min CDR. /// And transfers ownership of it to the liquidator with a new vault /// @return uint256 new vault created with the debt and collateral. /// @dev this function can only be called if vault CDR is under the bonus ratio. /// address who calls it will now own the debt and the collateral. function buyRiskDebtVault(uint256 vaultID) external vaultExists(vaultID) returns(uint256) { require( stabilityPool == address(0) || msg.sender == stabilityPool, "buy risky is disabled for public" ); uint256 vaultDebtNow = updateVaultDebt(vaultID); require(vaultDebtNow != 0, "Vault debt is 0"); ( uint256 collateralValueTimes100, uint256 debtValue ) = calculateCollateralProperties( vaultCollateral[vaultID], vaultDebtNow ); uint256 collateralPercentage = collateralValueTimes100 / (debtValue); require( (collateralPercentage*10) <= gainRatio, "Vault is not below risky collateral percentage" ); uint256 maiDebtTobePaid = (debtValue / (10**priceSourceDecimals)) - (collateralValueTimes100 / ( _minimumCollateralPercentage * (10**priceSourceDecimals))); //have enough MAI to bring vault to X CDR (presumably min) require(mai.balanceOf(msg.sender) >= maiDebtTobePaid, "Not enough mai to buy the risky vault"); //mai mai.safeTransferFrom(msg.sender, address(this), maiDebtTobePaid); totalBorrowed = totalBorrowed - (maiDebtTobePaid); // newVault for msg.sender uint256 newVault = createVault(); // updating vault collateral and debt details for the transfer of risky vault vaultCollateral[newVault] = vaultCollateral[vaultID]; accumulatedVaultDebt[newVault] = vaultDebtNow - maiDebtTobePaid; lastInterest[newVault] = block.timestamp; // resetting the vaultID vault info delete vaultCollateral[vaultID]; delete accumulatedVaultDebt[vaultID]; // lastInterest of vaultID would be block.timestamp, not reseting its timestamp emit BoughtRiskyDebtVault(vaultID, newVault, msg.sender, maiDebtTobePaid); return newVault; } } // File @openzeppelin/contracts/access/[email protected] // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File contracts/fixedInterestVaults/fixedQiVault.sol pragma solidity 0.8.11; /// @title Fixed Interest Vault /// @notice Single collateral lending manager with fixed rate interest. contract stableQiVault is fixedVault, Ownable { /// @dev Used to restrain the fee. Can only be up to 5% of the amount. uint256 constant FEE_MAX = 500; string private oracleType; constructor( address ethPriceSourceAddress, uint256 minimumCollateralPercentage, string memory name, string memory symbol, address _mai, address _collateral, string memory baseURI ) fixedVault( ethPriceSourceAddress, minimumCollateralPercentage, name, symbol, _mai, _collateral, baseURI ) { createVault(); addFrontEnd(0); } event UpdatedClosingFee(uint256 newFee); event UpdatedOpeningFee(uint256 newFee); event WithdrawInterest(uint256 earned); event UpdatedMinDebt(uint256 newMinDebt); event UpdatedMaxDebt(uint256 newMaxDebt); event UpdatedDebtRatio(uint256 _debtRatio); event UpdatedGainRatio(uint256 _gainRatio); event UpdatedEthPriceSource(address _ethPriceSourceAddress); event AddedFrontEnd(uint256 promoter); event RemovedFrontEnd(uint256 promoter); event UpdatedFrontEnd(uint256 promoter, uint256 newFee); event UpdatedFees(uint256 _adminFee, uint256 _refFee); event UpdatedMinCollateralRatio(uint256 newMinCollateralRatio); event UpdatedStabilityPool(address pool); event UpdatedInterestRate(uint256 interestRate); event BurnedToken(uint256 amount); event UpdatedTokenURI(string uri); event UpdatedAdmin(address newAdmin); event UpdatedRef(address newRef); event UpdatedOracleName(string oracle); modifier onlyOperators() { require(ref == msg.sender || adm == msg.sender || owner() == msg.sender, "Needs to be called by operators"); _; } modifier onlyAdmin() { require(adm == msg.sender, "Needs to be called by admin"); _; } /// @param _oracle name of the oracle used by the contract /// @notice sets the oracle name used by the contract. for visual purposes. function updateOracleName(string memory _oracle) external onlyOwner { oracleType = _oracle; emit UpdatedOracleName(_oracle); } /// @param _gainRatio sets the bonus earned from a liquidator /// @notice implements a setter for the bonus earned by a liquidator /// @dev fails if the bonus is less than 1 function setGainRatio(uint256 _gainRatio) external onlyOwner { require(_gainRatio >= 1000, "gainRatio cannot be less than or equal to 1000"); gainRatio = _gainRatio; emit UpdatedGainRatio(gainRatio); } /// @param _debtRatio sets the ratio of debt paid back by a liquidator /// @notice sets the ratio of the debt to be paid back /// @dev it divides the debt. 1/debtRatio. function setDebtRatio(uint256 _debtRatio) external onlyOwner { require(_debtRatio != 0, "Debt Ratio cannot be 0"); debtRatio = _debtRatio; emit UpdatedDebtRatio(debtRatio); } /// @param ethPriceSourceAddress is the address that provides the price of the collateral /// @notice sets the address used as oracle /// @dev Oracle price feed is used in here. Interface's available in the at /interfaces/IPriceSourceAll.sol function changeEthPriceSource(address ethPriceSourceAddress) external onlyOwner { require(ethPriceSourceAddress != address(0), "Ethpricesource cannot be zero address" ); ethPriceSource = IPriceSource(ethPriceSourceAddress); emit UpdatedEthPriceSource(ethPriceSourceAddress); } /// @param _pool is the address that can execute liquidations /// @notice sets the address used as stability pool for liquidations /// @dev if not set to address(0) then _pool is the only address able to liquidate function setStabilityPool(address _pool) external onlyOwner { require(_pool != address(0), "StabilityPool cannot be zero address" ); stabilityPool = _pool; emit UpdatedStabilityPool(stabilityPool); } /// @param _admin is the ratio earned by the address that maintains the market /// @param _ref is the ratio earned by the address that provides the borrowable asset /// @notice sets the interest rate split between the admin and ref /// @dev if not set to address(0) then _pool is the only address able to liquidate function setFees(uint256 _admin, uint256 _ref) external onlyOwner { require((_admin+_ref)==TEN_THOUSAND, "setFees: must equal 10000."); adminFee=_admin; refFee=_ref; emit UpdatedFees(adminFee, refFee); } /// @param minimumCollateralPercentage is the CDR that limits the amount borrowed /// @notice sets the CDR /// @dev only callable by owner of the contract function setMinCollateralRatio(uint256 minimumCollateralPercentage) external onlyOwner { _minimumCollateralPercentage = minimumCollateralPercentage; emit UpdatedMinCollateralRatio(_minimumCollateralPercentage); } /// @param _minDebt is minimum debt able to be borrowed by a vault. /// @notice sets the minimum debt. /// @dev dust protection function setMinDebt(uint256 _minDebt) external onlyOwner { require(_minDebt >=0, "setMinDebt: must be over 0."); minDebt = _minDebt; emit UpdatedMinDebt(minDebt); } /// @param _maxDebt is maximum debt able to be borrowed by a vault. /// @notice sets the maximum debt. /// @dev whale and liquidity protection. function setMaxDebt(uint256 _maxDebt) external onlyOwner { require(_maxDebt >=0, "setMaxDebt: must be over 0."); maxDebt = _maxDebt; emit UpdatedMaxDebt(maxDebt); } /// @param _ref is the address that provides the borrowable asset /// @notice sets the address that earns interest for providing a borrowable asset /// @dev cannot be address(0) function setRef(address _ref) external onlyOwner { require(_ref != address(0), "Reference Address cannot be zero"); ref = _ref; emit UpdatedRef(ref); } /// @param _adm is the ratio earned by the address that maintains the market /// @notice sets the address that earns interest for maintaining the market /// @dev cannot be address(0) function setAdmin(address _adm) external onlyOwner { require(_adm != address(0), "Admin Address cannot be zero"); adm = _adm; emit UpdatedAdmin(adm); } /// @param _openingFee is the fee charged to a vault when borrowing. /// @notice sets opening fee. /// @dev can only be up to 5% (FEE_MAX) of the amount. function setOpeningFee(uint256 _openingFee) external onlyOwner { require(_openingFee >= 0 && _openingFee <= FEE_MAX, "setOpeningFee: cannot be more than 5%"); openingFee = _openingFee; // emit event emit UpdatedOpeningFee(openingFee); } /// @param _closingFee is the fee charged to a vault when repaying. /// @notice sets closing fee. /// @dev can only be up to 5% (FEE_MAX) of the amount. function setClosingFee(uint256 _closingFee) external onlyOwner { require(_closingFee >= 0 && _closingFee <= FEE_MAX, "setClosingFee: cannot be more than 5%"); closingFee = _closingFee; // emit event emit UpdatedClosingFee(closingFee); } /// @param _promoter is a front end for the contract /// @notice adds a front end to earn opening/closing fees from borrowing/repaying. /// @dev can only be up to 5% (FEE_MAX) of the amount. function addFrontEnd(uint256 _promoter) public onlyOwner { require(_exists(_promoter), "addFrontEnd: Vault does not exist"); require(promoter[_promoter] == 0, "addFrontEnd: already added"); promoter[_promoter] = TEN_THOUSAND; emit AddedFrontEnd(_promoter); } /// @param _promoter is a front end for the contract /// @param cashback is the amount of fee not taken from a user. /// @notice updates the cashback variable for a given front end /// @dev can only be updated by the front end vault's owner function updateFrontEnd(uint256 _promoter, uint256 cashback) external frontExists(_promoter) onlyVaultOwner(_promoter) { require(cashback > 0 && cashback <= TEN_THOUSAND, "updateFrontEnd: cannot be 0"); promoter[_promoter] = cashback; emit UpdatedFrontEnd(_promoter, cashback); } /// @param _promoter is a front end for the contract /// @notice removes the ability for a front end to earn fees function removeFrontEnd(uint256 _promoter) external frontExists(_promoter) onlyOwner { require(_exists(_promoter), "removeFrontEnd: Vault does not exist"); require(promoter[_promoter] > 0, "removeFrontEnd: not a front end"); promoter[_promoter] = 0; emit RemovedFrontEnd(_promoter); } /// @notice withdraws earned interest by vault. function withdrawInterest() external onlyOperators nonReentrant { uint256 adm_fee = maiDebt*adminFee / TEN_THOUSAND; // Transfer mai.transfer(ref, (maiDebt-adm_fee) ); // cheaper and equivalent. mai.transfer(adm, adm_fee); emit WithdrawInterest(maiDebt); maiDebt = 0; } /// @param _iR is the fixed interest charged by a vault /// @notice sets the interest charged by a vault. function setInterestRate(uint256 _iR) external onlyOwner { iR = _iR; emit UpdatedInterestRate(iR); } /// @param amountToken is the amount of borrowable asset that is removed from the debt ceiling. /// @notice removes debt ceiling from the vault. /// @dev returns the asset to the owner so it can be redeployed at a later time. function burn(uint256 amountToken) external onlyAdmin { // Burn require(amountToken < mai.balanceOf(address(this)), "burn: Balance not enough"); mai.transfer(ref, amountToken); emit BurnedToken(amountToken); } /// @param _uri is the url for the nft metadata /// @notice updates the metadata /// @dev it currently uses an ipfs json function setTokenURI(string calldata _uri) external onlyOwner { uri = _uri; emit UpdatedTokenURI(uri); } function setRouter(address _router) external onlyOwner { router=_router; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"ethPriceSourceAddress","type":"address"},{"internalType":"uint256","name":"minimumCollateralPercentage","type":"uint256"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"address","name":"_mai","type":"address"},{"internalType":"address","name":"_collateral","type":"address"},{"internalType":"string","name":"baseURI","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"promoter","type":"uint256"}],"name":"AddedFrontEnd","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"BorrowToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"riskyVault","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newVault","type":"uint256"},{"indexed":false,"internalType":"address","name":"riskyVaultBuyer","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountPaidtoBuy","type":"uint256"}],"name":"BoughtRiskyDebtVault","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"BurnedToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultID","type":"uint256"},{"indexed":false,"internalType":"address","name":"creator","type":"address"}],"name":"CreateVault","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"DepositCollateral","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"DestroyVault","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultID","type":"uint256"},{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint256","name":"debtRepaid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"collateralLiquidated","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"closingFee","type":"uint256"}],"name":"LiquidateVault","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"closingFee","type":"uint256"}],"name":"PayBackToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"promoter","type":"uint256"}],"name":"RemovedFrontEnd","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"UpdatedAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"UpdatedClosingFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_debtRatio","type":"uint256"}],"name":"UpdatedDebtRatio","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_ethPriceSourceAddress","type":"address"}],"name":"UpdatedEthPriceSource","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_adminFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_refFee","type":"uint256"}],"name":"UpdatedFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"promoter","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"UpdatedFrontEnd","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_gainRatio","type":"uint256"}],"name":"UpdatedGainRatio","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"interestRate","type":"uint256"}],"name":"UpdatedInterestRate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMaxDebt","type":"uint256"}],"name":"UpdatedMaxDebt","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMinCollateralRatio","type":"uint256"}],"name":"UpdatedMinCollateralRatio","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMinDebt","type":"uint256"}],"name":"UpdatedMinDebt","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"UpdatedOpeningFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"oracle","type":"string"}],"name":"UpdatedOracleName","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newRef","type":"address"}],"name":"UpdatedRef","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"pool","type":"address"}],"name":"UpdatedStabilityPool","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"uri","type":"string"}],"name":"UpdatedTokenURI","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawCollateral","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"earned","type":"uint256"}],"name":"WithdrawInterest","type":"event"},{"inputs":[],"name":"_minimumCollateralPercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"accumulatedVaultDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_promoter","type":"uint256"}],"name":"addFrontEnd","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"adm","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"adminFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"_front","type":"uint256"}],"name":"borrowToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"buyRiskDebtVault","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"promoFee","type":"uint256"}],"name":"calculateFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"ethPriceSourceAddress","type":"address"}],"name":"changeEthPriceSource","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"checkCollateralPercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"checkCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"checkExtract","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"checkLiquidation","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"checkRiskyVault","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"closingFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collateral","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"createVault","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"debtRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimalDifferenceRaisedToTen","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"depositCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"destroyVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"ethPriceSource","outputs":[{"internalType":"contract IPriceSource","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gainRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getClosingFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDebtCeiling","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getEthPriceSource","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pay","type":"address"}],"name":"getPaid","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getPaid","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getTokenPriceSource","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalValueLocked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"iR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_collateral","type":"uint256"},{"internalType":"uint256","name":"debt","type":"uint256"}],"name":"isValidCollateral","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"lastInterest","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"},{"internalType":"uint256","name":"_front","type":"uint256"}],"name":"liquidateVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mai","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maiDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"maticDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"openingFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"_front","type":"uint256"}],"name":"payBackToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"_front","type":"uint256"}],"name":"paybackTokenAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"priceSourceDecimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"promoter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ref","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"refFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_promoter","type":"uint256"}],"name":"removeFrontEnd","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"router","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_adm","type":"address"}],"name":"setAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_closingFee","type":"uint256"}],"name":"setClosingFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_debtRatio","type":"uint256"}],"name":"setDebtRatio","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_admin","type":"uint256"},{"internalType":"uint256","name":"_ref","type":"uint256"}],"name":"setFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_gainRatio","type":"uint256"}],"name":"setGainRatio","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_iR","type":"uint256"}],"name":"setInterestRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxDebt","type":"uint256"}],"name":"setMaxDebt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"minimumCollateralPercentage","type":"uint256"}],"name":"setMinCollateralRatio","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minDebt","type":"uint256"}],"name":"setMinDebt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_openingFee","type":"uint256"}],"name":"setOpeningFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_ref","type":"address"}],"name":"setRef","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_router","type":"address"}],"name":"setRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pool","type":"address"}],"name":"setStabilityPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uri","type":"string"}],"name":"setTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stabilityPool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenPeg","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalBorrowed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_promoter","type":"uint256"},{"internalType":"uint256","name":"cashback","type":"uint256"}],"name":"updateFrontEnd","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_oracle","type":"string"}],"name":"updateOracleName","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"updateVaultDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"vaultCollateral","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vaultCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"vaultDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawInterest","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040526026805460ff60a01b1916600760a01b1790553480156200002457600080fd5b506040516200678b3803806200678b833981016040819052620000479162000c66565b868686868686868484828282600160008190555081600190805190602001906200007392919062000ad6565b5080516200008990600290602084019062000ad6565b50508151620000a19150600b90602084019062000ad6565b505050506001600160a01b038716620000b957600080fd5b85620000c457600080fd5b6032600f556000601055600c80546001600160a01b03808a166001600160a01b03199283161790925560238054821690556969e10de76676d08000006012556002601a5561044c601b55600d889055601c80548584169083168117909155601d8054938716939092169290921790556008601f556040805163313ce56760e01b8152905163313ce567916004818101926020929091908290030181865afa15801562000174573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200019a919062000d3a565b601d60009054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001ee573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000214919062000d3a565b62000220919062000d7c565b6200022d90600a62000ea1565b601e55505060248054336001600160a01b03199182168117909255602580549091169091179055506200027093506200026a925062000294915050565b62000298565b6200027a620002ea565b5062000287600062000358565b5050505050505062000f50565b3390565b602780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600e54600090620002fd81600162000eb2565b600e8190558111156200030f57600080fd5b6200031b338262000485565b604080518281523360208201527f8b6c1d05c678fa59695e26465a85918ce0fc63a88f74af53d1daef8f0a9c7804910160405180910390a1919050565b6200036262000626565b6000818152600360205260409020546001600160a01b0316620003d65760405162461bcd60e51b815260206004820152602160248201527f61646446726f6e74456e643a205661756c7420646f6573206e6f7420657869736044820152601d60fa1b60648201526084015b60405180910390fd5b60008181526017602052604090205415620004345760405162461bcd60e51b815260206004820152601a60248201527f61646446726f6e74456e643a20616c72656164792061646465640000000000006044820152606401620003cd565b600081815260176020526040908190206127109055517f9d7c7013bbd38c45562efb3f7031f740c1f8b8886dbbf421142755ed68339f4c906200047a9083815260200190565b60405180910390a150565b6001600160a01b038216620004dd5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401620003cd565b6000818152600360205260409020546001600160a01b031615620005445760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401620003cd565b6200055460008383600162000684565b6000818152600360205260409020546001600160a01b031615620005bb5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401620003cd565b6001600160a01b038216600081815260046020908152604080832080546001019055848352600390915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6027546001600160a01b03163314620006825760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620003cd565b565b6200069d84848484620006a360201b62003e511760201c565b50505050565b620006bc848484846200080760201b62003f8a1760201c565b6001811115620007355760405162461bcd60e51b815260206004820152603560248201527f455243373231456e756d657261626c653a20636f6e736563757469766520747260448201527f616e7366657273206e6f7420737570706f7274656400000000000000000000006064820152608401620003cd565b816001600160a01b03851662000794576200078e81600980546000838152600a60205260408120829055600182018355919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0155565b620007ba565b836001600160a01b0316856001600160a01b031614620007ba57620007ba858262000896565b6001600160a01b038416620007da57620007d48162000943565b62000800565b846001600160a01b0316846001600160a01b0316146200080057620008008482620009fd565b5050505050565b60018111156200069d576001600160a01b0384161562000851576001600160a01b038416600090815260046020526040812080548392906200084b90849062000ecd565b90915550505b6001600160a01b038316156200069d576001600160a01b038316600090815260046020526040812080548392906200088b90849062000eb2565b909155505050505050565b60006001620008b08462000a4e60201b620021171760201c565b620008bc919062000ecd565b60008381526008602052604090205490915080821462000910576001600160a01b03841660009081526007602090815260408083208584528252808320548484528184208190558352600890915290208190555b5060009182526008602090815260408084208490556001600160a01b039094168352600781528383209183525290812055565b600954600090620009579060019062000ecd565b6000838152600a60205260408120546009805493945090928490811062000982576200098262000ee7565b906000526020600020015490508060098381548110620009a657620009a662000ee7565b6000918252602080832090910192909255828152600a90915260408082208490558582528120556009805480620009e157620009e162000efd565b6001900381819060005260206000200160009055905550505050565b600062000a158362000a4e60201b620021171760201c565b6001600160a01b039093166000908152600760209081526040808320868452825280832085905593825260089052919091209190915550565b60006001600160a01b03821662000aba5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401620003cd565b506001600160a01b031660009081526004602052604090205490565b82805462000ae49062000f13565b90600052602060002090601f01602090048101928262000b08576000855562000b53565b82601f1062000b2357805160ff191683800117855562000b53565b8280016001018555821562000b53579182015b8281111562000b5357825182559160200191906001019062000b36565b5062000b6192915062000b65565b5090565b5b8082111562000b61576000815560010162000b66565b80516001600160a01b038116811462000b9457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f83011262000bc157600080fd5b81516001600160401b038082111562000bde5762000bde62000b99565b604051601f8301601f19908116603f0116810190828211818310171562000c095762000c0962000b99565b8160405283815260209250868385880101111562000c2657600080fd5b600091505b8382101562000c4a578582018301518183018401529082019062000c2b565b8382111562000c5c5760008385830101525b9695505050505050565b600080600080600080600060e0888a03121562000c8257600080fd5b62000c8d8862000b7c565b602089015160408a015191985096506001600160401b038082111562000cb257600080fd5b62000cc08b838c0162000baf565b965060608a015191508082111562000cd757600080fd5b62000ce58b838c0162000baf565b955062000cf560808b0162000b7c565b945062000d0560a08b0162000b7c565b935060c08a015191508082111562000d1c57600080fd5b5062000d2b8a828b0162000baf565b91505092959891949750929550565b60006020828403121562000d4d57600080fd5b815160ff8116811462000d5f57600080fd5b9392505050565b634e487b7160e01b600052601160045260246000fd5b600060ff821660ff84168082101562000d995762000d9962000d66565b90039392505050565b600181815b8085111562000de357816000190482111562000dc75762000dc762000d66565b8085161562000dd557918102915b93841c939080029062000da7565b509250929050565b60008262000dfc5750600162000e9b565b8162000e0b5750600062000e9b565b816001811462000e24576002811462000e2f5762000e4f565b600191505062000e9b565b60ff84111562000e435762000e4362000d66565b50506001821b62000e9b565b5060208310610133831016604e8410600b841016171562000e74575081810a62000e9b565b62000e80838362000da2565b806000190482111562000e975762000e9762000d66565b0290505b92915050565b600062000d5f60ff84168362000deb565b6000821982111562000ec85762000ec862000d66565b500190565b60008282101562000ee25762000ee262000d66565b500390565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b600181811c9082168062000f2857607f821691505b6020821081141562000f4a57634e487b7160e01b600052602260045260246000fd5b50919050565b61582b8062000f606000396000f3fe608060405234801561001057600080fd5b506004361061052f5760003560e01c80638da5cb5b116102af578063cc02ce2211610172578063e0df5b6f116100d9578063ece1373211610092578063ece1373214610b90578063f17336d714610ba3578063f1c91fa614610bac578063f2fde38b14610bb5578063f887ea4014610bc8578063ffc73da714610bdb57600080fd5b8063e0df5b6f14610b14578063e5f4dc9214610b27578063e985e9c514610b30578063eac989f814610b6c578063eb6a887d14610b74578063ec2e0ab314610b8757600080fd5b8063d0064c001161012b578063d0064c0014610a92578063d310f49b14610a9b578063d4a9b2c514610aae578063d73464cc14610ace578063d8dfeb4514610aee578063df98784614610b0157600080fd5b8063cc02ce2214610a46578063cd44db1b14610a59578063cdfedd6314610a63578063cea55f5714610a6e578063cf41d6f814610a77578063cf5f0f3c14610a7f57600080fd5b8063a57ff50311610216578063b3229a63116101cf578063b3229a63146109de578063b86f6aef146109f1578063b88d4fde14610a04578063c0d7865514610a17578063c71abb3214610a2a578063c87b56dd14610a3357600080fd5b8063a57ff50314610989578063a5e9883714610992578063a7c6a1001461099a578063a9c904b5146109a3578063b165ff0b146109b6578063b26025aa146109d657600080fd5b806397a41b8e1161026857806397a41b8e1461091f57806397ff37b91461093257806398c3f2db1461095257806398d721e01461095a578063a0be06f91461096d578063a22cb4651461097657600080fd5b80638da5cb5b146108c55780639035e4cb146108d657806393ee476a146108e957806394cd4ba7146108fc578063952cc86a1461090457806395d89b411461091757600080fd5b806342f371c6116103f75780636352211e1161035e57806370a082311161031757806370a0823114610868578063715018a61461087b578063728bbbb514610883578063767a7b051461088c57806385e290a31461089f57806386375994146108b257600080fd5b80636352211e146107f657806363b8817c146108095780636526941b1461081c578063687e8c171461082f5780636bc855cc14610842578063704b6c021461085557600080fd5b806356572ac0116103b057806356572ac01461078f578063570b2b84146107a25780635d12928b146107b55780635f84f302146107bd5780635ff09ac2146107d05780636234dc21146107e357600080fd5b806342f371c6146107145780634c19386c146107275780634f558e79146107305780634f6ccce7146107435780635357b9891461075657806354fd4d501461076957600080fd5b806321a78f681161049b5780633128ef27116104545780633128ef27146106a257806338536275146106b55780633db99177146106c857806340803854146106db57806342842e0e146106ee57806342966c681461070157600080fd5b806321a78f681461063757806323b872dd1461064a578063241a545a1461065d5780632df87573146106665780632f745c5914610686578063311f392a1461069957600080fd5b8063081812fc116104ed578063081812fc146105cc578063095ea7b3146105df5780630b78f9c0146105f257806311b4a8321461060557806318160ddd146106265780631c883e7b1461062e57600080fd5b806263750c1461053457806301ffc9a71461053e578063048c661d1461056657806304d7aef21461059157806306fdde03146105a457806307960532146105b9575b600080fd5b61053c610bee565b005b61055161054c366004614eef565b610e12565b60405190151581526020015b60405180910390f35b602354610579906001600160a01b031681565b6040516001600160a01b03909116815260200161055d565b602454610579906001600160a01b031681565b6105ac610e23565b60405161055d9190614f6b565b61053c6105c7366004614f9a565b610eb5565b6105796105da366004614fb5565b610f76565b61053c6105ed366004614fce565b610f9d565b61053c610600366004614ff8565b6110b3565b610618610613366004614fb5565b61115d565b60405190815260200161055d565b600954610618565b610618600f5481565b602554610579906001600160a01b031681565b61053c61065836600461501a565b61120f565b61061860135481565b610618610674366004614fb5565b60156020526000908152604090205481565b610618610694366004614fce565b611240565b610618601b5481565b61053c6106b0366004615056565b6112d6565b61053c6106c3366004614fb5565b6115f7565b61053c6106d6366004614fb5565b611634565b61053c6106e9366004614fb5565b6116d1565b61053c6106fc36600461501a565b6117d9565b61053c61070f366004614fb5565b6117f4565b600c54610579906001600160a01b031681565b61061860205481565b61055161073e366004614fb5565b6119b2565b610618610751366004614fb5565b6119bd565b610618610764366004615056565b611a50565b60265461077d90600160a01b900460ff1681565b60405160ff909116815260200161055d565b61061861079d366004614fb5565b611aff565b601d54610579906001600160a01b031681565b610618611bf0565b61053c6107cb366004614fb5565b611c59565b61053c6107de366004614fb5565b611c96565b61053c6107f1366004614fb5565b611e0c565b610579610804366004614fb5565b611e49565b61053c610817366004614f9a565b611ea9565b61053c61082a366004614fb5565b611f53565b61055161083d366004614ff8565b611f90565b61053c610850366004614f9a565b611fbf565b61053c610863366004614f9a565b61206b565b610618610876366004614f9a565b612117565b61053c61219d565b61061860105481565b61053c61089a366004614ff8565b6121af565b61053c6108ad366004614fb5565b612391565b61053c6108c0366004614fb5565b6124f7565b6027546001600160a01b0316610579565b6106186108e4366004614fb5565b612594565b6106186108f7366004614fb5565b61290b565b610618612972565b61053c610912366004614ff8565b6129e4565b6105ac612ec8565b61053c61092d366004615056565b612ed7565b610618610940366004614fb5565b60166020526000908152604090205481565b61061861329e565b61053c610968366004614f9a565b6132e8565b61061860185481565b61053c610984366004615090565b6133a0565b610618601e5481565b600f54610618565b610618600e5481565b61053c6109b1366004615153565b6133ab565b6106186109c4366004614f9a565b60216020526000908152604090205481565b6106186133f6565b6105516109ec366004614fb5565b613482565b6105516109ff366004614fb5565b61353c565b61053c610a1236600461519c565b6135df565b61053c610a25366004614f9a565b613617565b610618601f5481565b6105ac610a41366004614fb5565b613641565b61053c610a54366004614ff8565b6136e7565b6305f5e100610618565b6106186305f5e10081565b610618601a5481565b61053c61385c565b61053c610a8d366004615056565b6138f8565b61061860125481565b610618610aa9366004614fb5565b613a46565b610618610abc366004614fb5565b60146020526000908152604090205481565b610618610adc366004614fb5565b60176020526000908152604090205481565b601c54610579906001600160a01b031681565b610618610b0f366004614fb5565b613a52565b61053c610b22366004615218565b613ae4565b610618600d5481565b610551610b3e36600461528a565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205460ff1690565b6105ac613b29565b61053c610b82366004614fb5565b613bb7565b61061860195481565b61053c610b9e366004614ff8565b613c3a565b61061860115481565b61061860225481565b61053c610bc3366004614f9a565b613d35565b602654610579906001600160a01b031681565b61053c610be9366004614fb5565b613dab565b6025546001600160a01b0316331480610c1157506024546001600160a01b031633145b80610c35575033610c2a6027546001600160a01b031690565b6001600160a01b0316145b610c865760405162461bcd60e51b815260206004820152601f60248201527f4e6565647320746f2062652063616c6c6564206279206f70657261746f72730060448201526064015b60405180910390fd5b610c8e614012565b6000612710601854602254610ca391906152d3565b610cad91906152f2565b601d546025546022549293506001600160a01b039182169263a9059cbb9290911690610cda908590615314565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015610d25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d49919061532b565b50601d546024805460405163a9059cbb60e01b81526001600160a01b0391821660048201529182018490529091169063a9059cbb906044016020604051808303816000875af1158015610da0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc4919061532b565b507fc73fb14682b9d51008c1faff296cc9b351c0597de5e25b4ffa158f47f8254e4c602254604051610df891815260200190565b60405180910390a1506000602255610e106001600055565b565b6000610e1d8261406c565b92915050565b606060018054610e3290615348565b80601f0160208091040260200160405190810160405280929190818152602001828054610e5e90615348565b8015610eab5780601f10610e8057610100808354040283529160200191610eab565b820191906000526020600020905b815481529060010190602001808311610e8e57829003601f168201915b5050505050905090565b610ebd614091565b6001600160a01b038116610f215760405162461bcd60e51b815260206004820152602560248201527f4574687072696365736f757263652063616e6e6f74206265207a65726f206164604482015264647265737360d81b6064820152608401610c7d565b600c80546001600160a01b0319166001600160a01b0383169081179091556040519081527fc525e5fed1508c998d3f14bf52f933df1dd16dbf48e2944c426be721e268b755906020015b60405180910390a150565b6000610f81826140eb565b506000908152600560205260409020546001600160a01b031690565b6000610fa882611e49565b9050806001600160a01b0316836001600160a01b031614156110165760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610c7d565b336001600160a01b038216148061103257506110328133610b3e565b6110a45760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610c7d565b6110ae838361413b565b505050565b6110bb614091565b6127106110c8828461537d565b146111155760405162461bcd60e51b815260206004820152601a60248201527f736574466565733a206d75737420657175616c2031303030302e0000000000006044820152606401610c7d565b6018829055601981905560408051838152602081018390527f4d32f38862d5eb71edfefb7955873bd55920dc98159b6f53f8be62fbf0bebb4b91015b60405180910390a15050565b60008061116983613a46565b6000848152601460205260409020549091501580611185575080155b8061119657506111948361353c565b155b156111a45750600092915050565b6000838152601460205260408120546111bd90836141a9565b915050806111cf575060009392505050565b601f546111dd90600a615479565b6111e790826152f2565b90506000601a54826111f991906152f2565b905060115481116112075750805b949350505050565b6112193382614232565b6112355760405162461bcd60e51b8152600401610c7d90615485565b6110ae8383836142b0565b600061124b83612117565b82106112ad5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610c7d565b506001600160a01b03919091166000908152600760209081526040808320938352929052205490565b806112e081614421565b6112fc5760405162461bcd60e51b8152600401610c7d906154d2565b60008181526017602052604090205461271010801590611329575060008181526017602052604090205415155b6113455760405162461bcd60e51b8152600401610c7d90615509565b8361134f81614421565b61136b5760405162461bcd60e51b8152600401610c7d90615536565b6026546001600160a01b0316158061138d57506026546001600160a01b031633145b6113a95760405162461bcd60e51b8152600401610c7d90615564565b601d546040516370a0823160e01b815233600482015285916001600160a01b0316906370a0823190602401602060405180830381865afa1580156113f1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611415919061558d565b101561145b5760405162461bcd60e51b8152602060048201526015602482015274546f6b656e2062616c616e636520746f6f206c6f7760581b6044820152606401610c7d565b60006114668661290b565b9050848110156114c85760405162461bcd60e51b815260206004820152602760248201527f5661756c742064656274206c657373207468616e20616d6f756e7420746f20706044820152666179206261636b60c81b6064820152608401610c7d565b6011546114d58683615314565b1015806114e157508085145b6114fd5760405162461bcd60e51b8152600401610c7d906155a6565b600f54600085815260176020526040812054909161151c918890611a50565b90506115288683615314565b60008881526015602090815260408083209390935560149052205461154e908290615314565b60008881526014602052604080822092909255868152205461157190829061537d565b60008681526014602090815260409091209190915554611592908790615314565b602055601d546115ad906001600160a01b031633308961443e565b60408051888152602081018890529081018290527f31f96762af4051f367185773cc2f55bfb112a6c114b3407ded1f321a9eb199ac9060600160405180910390a150505050505050565b6115ff614091565b600d8190556040518181527fc0880963f3abc486dbb8b8f04ba4ce47c5b5cd3c59b6b7655f6011da0bf3365090602001610f6b565b61163c614091565b6101f481111561169c5760405162461bcd60e51b815260206004820152602560248201527f736574436c6f73696e674665653a2063616e6e6f74206265206d6f7265207468604482015264616e20352560d81b6064820152608401610c7d565b600f8190556040518181527fc1b83121984ef8e824a0babc08fc162077c0716a4dc307121f306e6dfb13806c90602001610f6b565b6116d9614091565b6116e281614421565b6117385760405162461bcd60e51b815260206004820152602160248201527f61646446726f6e74456e643a205661756c7420646f6573206e6f7420657869736044820152601d60fa1b6064820152608401610c7d565b600081815260176020526040902054156117945760405162461bcd60e51b815260206004820152601a60248201527f61646446726f6e74456e643a20616c72656164792061646465640000000000006044820152606401610c7d565b600081815260176020526040908190206127109055517f9d7c7013bbd38c45562efb3f7031f740c1f8b8886dbbf421142755ed68339f4c90610f6b9083815260200190565b6110ae838383604051806020016040528060008152506135df565b6024546001600160a01b0316331461184e5760405162461bcd60e51b815260206004820152601b60248201527f4e6565647320746f2062652063616c6c65642062792061646d696e00000000006044820152606401610c7d565b601d546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015611896573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118ba919061558d565b81106119085760405162461bcd60e51b815260206004820152601860248201527f6275726e3a2042616c616e6365206e6f7420656e6f75676800000000000000006044820152606401610c7d565b601d5460255460405163a9059cbb60e01b81526001600160a01b0391821660048201526024810184905291169063a9059cbb906044016020604051808303816000875af115801561195d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611981919061532b565b506040518181527fb1f67ade07cda330ac167f4fcc4c01b94fdfc04d401cf85e487f0a5b8b98e75f90602001610f6b565b6000610e1d82614421565b60006119c860095490565b8210611a2b5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610c7d565b60098281548110611a3e57611a3e6155e7565b90600052602060002001549050919050565b6000808215611aae5761271080611a6561329e565b611a6f91906152d3565b611a7991906152d3565b836305f5e100611a8988886152d3565b611a9391906152d3565b611a9d91906152d3565b611aa791906152f2565b9050611ae9565b612710611ab961329e565b611ac391906152d3565b6305f5e100611ad287876152d3565b611adc91906152d3565b611ae691906152f2565b90505b601e54611af690826152f2565b95945050505050565b6000818152601460205260408120541580611b205750611b1e8261353c565b155b15611b2d57506000919050565b6000611b3883613a46565b60008481526014602052604081205491925090611b5590836141a9565b9150506000601a5482611b6891906152f2565b905080611b7a57506000949350505050565b601154601f54611b8b90600a615479565b611b9590836152f2565b11611bd457601e54611ba561329e565b6103e8601b5485611bb691906152d3565b611bc091906152f2565b611bca91906152f2565b611af691906152f2565b601e54611bdf61329e565b6103e8601b5484611bb691906152d3565b600e54600090611c0181600161537d565b600e819055811115611c1257600080fd5b611c1c33826144a9565b604080518281523360208201527f8b6c1d05c678fa59695e26465a85918ce0fc63a88f74af53d1daef8f0a9c7804910160405180910390a1919050565b611c61614091565b60138190556040518181527f323264e3ca065ee856fe1b11204d8896a783bccf148380ac5d7362eb5c4c36a890602001610f6b565b80611ca081614421565b611cbc5760405162461bcd60e51b8152600401610c7d906154d2565b60008181526017602052604090205461271010801590611ce9575060008181526017602052604090205415155b611d055760405162461bcd60e51b8152600401610c7d90615509565b611d0d614091565b611d1682614421565b611d6e5760405162461bcd60e51b8152602060048201526024808201527f72656d6f766546726f6e74456e643a205661756c7420646f6573206e6f7420656044820152631e1a5cdd60e21b6064820152608401610c7d565b600082815260176020526040902054611dc95760405162461bcd60e51b815260206004820152601f60248201527f72656d6f766546726f6e74456e643a206e6f7420612066726f6e7420656e64006044820152606401610c7d565b60008281526017602052604080822091909155517f9b9f950fb3755096dbbe8b1519e73f7c6d1a0507f514fced444919530c00d719906111519084815260200190565b611e14614091565b60118190556040518181527f4533506fbaba6b18743358b6e6fb9392e8cb21757487b68d232a01b140bbec0190602001610f6b565b6000818152600360205260408120546001600160a01b031680610e1d5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610c7d565b611eb1614012565b6001600160a01b038116600090815260216020526040902054611f165760405162461bcd60e51b815260206004820152601c60248201527f446f6e2774206861766520616e797468696e6720666f7220796f752e000000006044820152606401610c7d565b6001600160a01b0380821660009081526021602052604081208054919055601c549091611f4591168383614624565b50611f506001600055565b50565b611f5b614091565b60128190556040518181527f1dd8f42ee4750a70f6662d1383372472422592497256d506437e35b3fa914d9b90602001610f6b565b6000806000611f9f85856141a9565b90925090506000611fb082846152f2565b600d5411159695505050505050565b611fc7614091565b6001600160a01b03811661201d5760405162461bcd60e51b815260206004820181905260248201527f5265666572656e636520416464726573732063616e6e6f74206265207a65726f6044820152606401610c7d565b602580546001600160a01b0319166001600160a01b0383169081179091556040519081527f8ed6553fa1e634b0152cd3539c572bee8c662e446820646d73a0e1b47776af9390602001610f6b565b612073614091565b6001600160a01b0381166120c95760405162461bcd60e51b815260206004820152601c60248201527f41646d696e20416464726573732063616e6e6f74206265207a65726f000000006044820152606401610c7d565b602480546001600160a01b0319166001600160a01b0383169081179091556040519081527ffce52dd00c7849a7f2602c1f189745238d6a2db16fabf54376ce24cc2fa3d57f90602001610f6b565b60006001600160a01b0382166121815760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610c7d565b506001600160a01b031660009081526004602052604090205490565b6121a5614091565b610e106000614654565b816121b981614421565b6121d55760405162461bcd60e51b8152600401610c7d90615536565b336121df82611e49565b6001600160a01b0316146122055760405162461bcd60e51b8152600401610c7d906155fd565b61220d614012565b6000838152601460205260409020548211156122795760405162461bcd60e51b815260206004820152602560248201527f5661756c7420646f6573206e6f74206861766520656e6f75676820636f6c6c616044820152641d195c985b60da1b6064820152608401610c7d565b600083815260146020526040812054612293908490615314565b905060006122a08561290b565b90508015612324576122b28282611f90565b6123245760405162461bcd60e51b815260206004820152603e60248201527f5769746864726177616c20776f756c6420707574207661756c742062656c6f7760448201527f206d696e696d756d20636f6c6c61746572616c2070657263656e7461676500006064820152608401610c7d565b6000858152601460205260409020829055601c5461234c906001600160a01b03163386614624565b60408051868152602081018690527f6c0ea3bea9dd66afa8f9d39d6eb93d833466190330813b42835efc650dca4cb9910160405180910390a150506110ae6001600055565b8061239b81614421565b6123b75760405162461bcd60e51b8152600401610c7d90615536565b336123c182611e49565b6001600160a01b0316146123e75760405162461bcd60e51b8152600401610c7d906155fd565b6123ef614012565b6123f882613a46565b156124455760405162461bcd60e51b815260206004820152601a60248201527f5661756c7420686173206f75747374616e64696e6720646562740000000000006044820152606401610c7d565b600082815260146020526040902054156124875761248761246583611e49565b600084815260146020526040902054601c546001600160a01b03169190614624565b612490826146a6565b600082815260146020908152604080832083905560158252808320839055601682528083209290925590518381527f4fe08624ee65b341c38ab9693d216b909d4ddee1bc8d3fe0fea14026c361b465910160405180910390a16124f36001600055565b5050565b6124ff614091565b6101f481111561255f5760405162461bcd60e51b815260206004820152602560248201527f7365744f70656e696e674665653a2063616e6e6f74206265206d6f7265207468604482015264616e20352560d81b6064820152608401610c7d565b60108190556040518181527fc4ced91ca77dc4287a54d9bd9b15c69b3aba262e30eba7c93301c48606019c9490602001610f6b565b6000816125a081614421565b6125bc5760405162461bcd60e51b8152600401610c7d90615536565b6023546001600160a01b031615806125de57506023546001600160a01b031633145b61262a5760405162461bcd60e51b815260206004820181905260248201527f627579207269736b792069732064697361626c656420666f72207075626c69636044820152606401610c7d565b60006126358461290b565b9050806126765760405162461bcd60e51b815260206004820152600f60248201526e05661756c742064656274206973203608c1b6044820152606401610c7d565b600084815260146020526040812054819061269190846141a9565b909250905060006126a282846152f2565b601b549091506126b382600a6152d3565b11156127185760405162461bcd60e51b815260206004820152602e60248201527f5661756c74206973206e6f742062656c6f77207269736b7920636f6c6c61746560448201526d72616c2070657263656e7461676560901b6064820152608401610c7d565b6000601f54600a6127299190615479565b600d5461273691906152d3565b61274090856152f2565b601f5461274e90600a615479565b61275890856152f2565b6127629190615314565b601d546040516370a0823160e01b815233600482015291925082916001600160a01b03909116906370a0823190602401602060405180830381865afa1580156127af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127d3919061558d565b101561282f5760405162461bcd60e51b815260206004820152602560248201527f4e6f7420656e6f756768206d616920746f2062757920746865207269736b79206044820152641d985d5b1d60da1b6064820152608401610c7d565b601d54612847906001600160a01b031633308461443e565b806020546128559190615314565b6020556000612862611bf0565b60008a8152601460205260408082205483835291205590506128848287615314565b600082815260156020818152604080842094909455601681528383204290558c8352601481528383208390559081528282209190915581518b815290810183905233818301526060810184905290517fa4cf7276e26bb566de2c7540759e85736eb743807343fd27e6e679b20e8814419181900360800190a1965050505050505b50919050565b600080600061291984614749565b915091508160225461292b919061537d565b60225560205461293c90839061537d565b602055601354156129595760008481526016602052604090204290555b6000938452601560205260409093208390555090919050565b601d546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa1580156129bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129df919061558d565b905090565b806129ee81614421565b612a0a5760405162461bcd60e51b8152600401610c7d906154d2565b60008181526017602052604090205461271010801590612a37575060008181526017602052604090205415155b612a535760405162461bcd60e51b8152600401610c7d90615509565b82612a5d81614421565b612a795760405162461bcd60e51b8152600401610c7d90615536565b6023546001600160a01b03161580612a9b57506023546001600160a01b031633145b612af25760405162461bcd60e51b815260206004820152602260248201527f6c69717569646174696f6e2069732064697361626c656420666f72207075626c604482015261696360f01b6064820152608401610c7d565b6000612afd8561290b565b600086815260146020526040812054919250908190612b1c90846141a9565b915091508260001415612b635760405162461bcd60e51b815260206004820152600f60248201526e05661756c742064656274206973203608c1b6044820152606401610c7d565b6000612b6f82846152f2565b9050600d548110612bdb5760405162461bcd60e51b815260206004820152603060248201527f5661756c74206973206e6f742062656c6f77206d696e696d756d20636f6c6c6160448201526f746572616c2070657263656e7461676560801b6064820152608401610c7d565b601b54612be982600a6152d3565b11612c365760405162461bcd60e51b815260206004820152601d60248201527f5661756c74206973206e6f742061626f7665206761696e20726174696f0000006044820152606401610c7d565b601f54612c4490600a615479565b612c4e90836152f2565b91506000601a5483612c6091906152f2565b90506011548111612c6e5750815b601d546040516370a0823160e01b815233600482015282916001600160a01b0316906370a0823190602401602060405180830381865afa158015612cb6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cda919061558d565b1015612d425760405162461bcd60e51b815260206004820152603160248201527f546f6b656e2062616c616e636520746f6f206c6f7720746f20706179206f6666604482015270081bdd5d1cdd185b991a5b99c81919589d607a1b6064820152608401610c7d565b80602054612d509190615314565b6020556000612d5e8a611aff565b9050612d6a8287615314565b60008b815260156020908152604080832093909355600f548c83526017909152918120549091612d9b918590611a50565b60008c815260146020526040902054909150612db8908290615314565b60008c815260146020526040808220929092558b81522054612ddb90829061537d565b60008b815260146020526040808220929092558c81522054612dfe908390615314565b60008c815260146020908152604080832093909355338252602190522054612e2790839061537d565b33600081815260216020526040902091909155601d54612e54916001600160a01b0390911690308661443e565b7f4d151d3a98b83151d51917640c221f8c8e3c054422ea1b48dcbbd57e3f4210d58b612e7f8d611e49565b604080519283526001600160a01b0390911660208301523390820152606081018590526080810184905260a0810183905260c00160405180910390a15050505050505050505050565b606060028054610e3290615348565b80612ee181614421565b612efd5760405162461bcd60e51b8152600401610c7d906154d2565b60008181526017602052604090205461271010801590612f2a575060008181526017602052604090205415155b612f465760405162461bcd60e51b8152600401610c7d90615509565b83612f5081614421565b612f6c5760405162461bcd60e51b8152600401610c7d90615536565b33612f7682611e49565b6001600160a01b031614612f9c5760405162461bcd60e51b8152600401610c7d906155fd565b612fa4614012565b60008411612ff45760405162461bcd60e51b815260206004820152601b60248201527f4d75737420626f72726f77206e6f6e2d7a65726f20616d6f756e7400000000006044820152606401610c7d565b612ffc612972565b8411156130635760405162461bcd60e51b815260206004820152602f60248201527f626f72726f77546f6b656e3a2043616e6e6f74206d696e74206f76657220617660448201526e30b4b630b136329039bab838363c9760891b6064820152608401610c7d565b60008461306f8761290b565b613079919061537d565b90506012548111156130d85760405162461bcd60e51b815260206004820152602260248201527f626f72726f77546f6b656e3a206d6178206c6f616e2063617020726561636865604482015261321760f11b6064820152608401610c7d565b6130e186613a46565b81116130ec57600080fd5b6000868152601460205260409020546131059082611f90565b6131775760405162461bcd60e51b815260206004820152603a60248201527f426f72726f7720776f756c6420707574207661756c742062656c6f77206d696e60448201527f696d756d20636f6c6c61746572616c2070657263656e746167650000000000006064820152608401610c7d565b6011548561318488613a46565b61318e919061537d565b10156131ac5760405162461bcd60e51b8152600401610c7d906155a6565b600086815260156020908152604080832084905560105487845260179092528220546131da91908490611a50565b6000888152601460205260409020549091506131f7908290615314565b60008881526014602052604080822092909255868152205461321a90829061537d565b600086815260146020526040902055601d54613240906001600160a01b03163388614624565b8560205461324e919061537d565b6020908155604080518981529182018890527f3e08df88d8e28f37df9bf227d3142ac506a364403445661a60891a49ed6792ca910160405180910390a150506132976001600055565b5050505050565b600c54604080516350d25bcd60e01b815290516000926001600160a01b0316916350d25bcd9160048083019260209291908290030181865afa1580156129bb573d6000803e3d6000fd5b6132f0614091565b6001600160a01b0381166133525760405162461bcd60e51b8152602060048201526024808201527f53746162696c697479506f6f6c2063616e6e6f74206265207a65726f206164646044820152637265737360e01b6064820152608401610c7d565b602380546001600160a01b0319166001600160a01b0383169081179091556040519081527f0644c4f539d7f787d2287c12d9425e80aefc8bdae99c70af4ca66fb0742577e890602001610f6b565b6124f33383836147ee565b6133b3614091565b80516133c6906028906020840190614dcc565b507f0d82453dd4ad18b5ce3db08c34a39340ad2bf15046a7d0e86aa075483eb121d881604051610f6b9190614f6b565b601c546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa15801561343f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613463919061558d565b601e5461346e61329e565b61347891906152d3565b6129df91906152d3565b60008161348e81614421565b6134aa5760405162461bcd60e51b8152600401610c7d90615536565b60006134b584613a46565b60008581526014602052604090205490915015806134d1575080155b156134e0576000925050612905565b60008481526014602052604081205481906134fb90846141a9565b9092509050600061350c82846152f2565b601b5490915061351d82600a6152d3565b1161352f576001955050505050612905565b6000955050505050612905565b60008161354881614421565b6135645760405162461bcd60e51b8152600401610c7d90615536565b600061356f84613a46565b600085815260146020526040902054909150158061358b575080155b1561359a576000925050612905565b60008481526014602052604081205481906135b590846141a9565b909250905060006135c682846152f2565b9050600d5481101561352f576001955050505050612905565b6135e93383614232565b6136055760405162461bcd60e51b8152600401610c7d90615485565b613611848484846148bd565b50505050565b61361f614091565b602680546001600160a01b0319166001600160a01b0392909216919091179055565b606061364c82614421565b61365557600080fd5b600b805461366290615348565b80601f016020809104026020016040519081016040528092919081815260200182805461368e90615348565b80156136db5780601f106136b0576101008083540402835291602001916136db565b820191906000526020600020905b8154815290600101906020018083116136be57829003601f168201915b50505050509050919050565b816136f181614421565b61370d5760405162461bcd60e51b8152600401610c7d906154d2565b6000818152601760205260409020546127101080159061373a575060008181526017602052604090205415155b6137565760405162461bcd60e51b8152600401610c7d90615509565b8261376081614421565b61377c5760405162461bcd60e51b8152600401610c7d90615536565b3361378682611e49565b6001600160a01b0316146137ac5760405162461bcd60e51b8152600401610c7d906155fd565b6000831180156137be57506127108311155b61380a5760405162461bcd60e51b815260206004820152601b60248201527f75706461746546726f6e74456e643a2063616e6e6f74206265203000000000006044820152606401610c7d565b60008481526017602090815260409182902085905581518681529081018590527fbfdd5aecf44aa804bf11f070a41765d280dab82adbfd1c55e1e85b7d5b7920b491015b60405180910390a150505050565b613864614012565b336000908152602160205260409020546138c05760405162461bcd60e51b815260206004820152601c60248201527f446f6e2774206861766520616e797468696e6720666f7220796f752e000000006044820152606401610c7d565b3360008181526021602052604081208054919055601c5490916138ed916001600160a01b03169083614624565b50610e106001600055565b8061390281614421565b61391e5760405162461bcd60e51b8152600401610c7d906154d2565b6000818152601760205260409020546127101080159061394b575060008181526017602052604090205415155b6139675760405162461bcd60e51b8152600401610c7d90615509565b8361397181614421565b61398d5760405162461bcd60e51b8152600401610c7d90615536565b6026546001600160a01b031615806139af57506026546001600160a01b031633145b6139cb5760405162461bcd60e51b8152600401610c7d90615564565b42841015613a265760405162461bcd60e51b815260206004820152602260248201527f7061796261636b546f6b656e416c6c3a20646561646c696e6520657870697265604482015261321760f11b6064820152608401610c7d565b6000613a318661290b565b9050613a3e8682866112d6565b505050505050565b60008061120783614749565b600081613a5e81614421565b613a7a5760405162461bcd60e51b8152600401610c7d90615536565b6000613a8584613a46565b6000858152601460205260409020549091501580613aa1575080155b15613ab0576000925050612905565b6000848152601460205260408120548190613acb90846141a9565b9092509050613ada81836152f2565b9695505050505050565b613aec614091565b613af8600b8383614e50565b507ffda45751019c07e08a3ebf7d73a4aea1a6c36bee12d87089096012911a756ab5600b6040516111519190615634565b600b8054613b3690615348565b80601f0160208091040260200160405190810160405280929190818152602001828054613b6290615348565b8015613baf5780601f10613b8457610100808354040283529160200191613baf565b820191906000526020600020905b815481529060010190602001808311613b9257829003601f168201915b505050505081565b613bbf614091565b80613c055760405162461bcd60e51b815260206004820152601660248201527504465627420526174696f2063616e6e6f7420626520360541b6044820152606401610c7d565b601a8190556040518181527f199e93b2fae27b389e2d09761871573f60121b8521be96b8f28c83bf94846ac290602001610f6b565b81613c4481614421565b613c605760405162461bcd60e51b8152600401610c7d90615536565b6026546001600160a01b03161580613c8257506026546001600160a01b031633145b613c9e5760405162461bcd60e51b8152600401610c7d90615564565b600083815260146020526040812054613cb890849061537d565b600085815260146020526040902054909150811015613cd657600080fd5b6000848152601460205260409020819055601c54613cff906001600160a01b031633308661443e565b60408051858152602081018590527f52c4e7127ec34e8fc95f09ce2d06b4f00acca12ccbcdfb246ef67ee6aefe068d910161384e565b613d3d614091565b6001600160a01b038116613da25760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610c7d565b611f5081614654565b613db3614091565b6103e8811015613e1c5760405162461bcd60e51b815260206004820152602e60248201527f6761696e526174696f2063616e6e6f74206265206c657373207468616e206f7260448201526d020657175616c20746f20313030360941b6064820152608401610c7d565b601b8190556040518181527fb6d384ad48d9c5c042c81fa0f88d8061ef87b38475101d6aa5f9ae5a8274a64e90602001610f6b565b613e5d84848484613f8a565b6001811115613ecc5760405162461bcd60e51b815260206004820152603560248201527f455243373231456e756d657261626c653a20636f6e7365637574697665207472604482015274185b9cd9995c9cc81b9bdd081cdd5c1c1bdc9d1959605a1b6064820152608401610c7d565b816001600160a01b038516613f2857613f2381600980546000838152600a60205260408120829055600182018355919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0155565b613f4b565b836001600160a01b0316856001600160a01b031614613f4b57613f4b85826148f0565b6001600160a01b038416613f6757613f628161498d565b613297565b846001600160a01b0316846001600160a01b031614613297576132978482614a3c565b6001811115613611576001600160a01b03841615613fd0576001600160a01b03841660009081526004602052604081208054839290613fca908490615314565b90915550505b6001600160a01b03831615613611576001600160a01b0383166000908152600460205260408120805483929061400790849061537d565b909155505050505050565b600260005414156140655760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610c7d565b6002600055565b60006001600160e01b0319821663780e9d6360e01b1480610e1d5750610e1d82614a80565b6027546001600160a01b03163314610e105760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c7d565b6140f481614421565b611f505760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610c7d565b600081815260056020526040902080546001600160a01b0319166001600160a01b038416908117909155819061417082611e49565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000806141b461329e565b6141bd57600080fd5b6000601e546141ca61329e565b6141d490876152d3565b6141de91906152d3565b9050848110156141ed57600080fd5b60006141fd6305f5e100866152d3565b90508481101561420c57600080fd5b60006142198360646152d3565b905082811161422757600080fd5b969095509350505050565b60008061423e83611e49565b9050806001600160a01b0316846001600160a01b0316148061428557506001600160a01b0380821660009081526006602090815260408083209388168352929052205460ff165b806112075750836001600160a01b031661429e84610f76565b6001600160a01b031614949350505050565b826001600160a01b03166142c382611e49565b6001600160a01b0316146142e95760405162461bcd60e51b8152600401610c7d906156dc565b6001600160a01b03821661434b5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610c7d565b6143588383836001614ad0565b826001600160a01b031661436b82611e49565b6001600160a01b0316146143915760405162461bcd60e51b8152600401610c7d906156dc565b600081815260056020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260048552838620805460001901905590871680865283862080546001019055868652600390945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000908152600360205260409020546001600160a01b0316151590565b6040516001600160a01b03808516602483015283166044820152606481018290526136119085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614adc565b6001600160a01b0382166144ff5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610c7d565b61450881614421565b156145555760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610c7d565b614563600083836001614ad0565b61456c81614421565b156145b95760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610c7d565b6001600160a01b038216600081815260046020908152604080832080546001019055848352600390915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6040516001600160a01b0383166024820152604481018290526110ae90849063a9059cbb60e01b90606401614472565b602780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006146b182611e49565b90506146c1816000846001614ad0565b6146ca82611e49565b600083815260056020908152604080832080546001600160a01b03199081169091556001600160a01b0385168085526004845282852080546000190190558785526003909352818420805490911690555192935084927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b60008181526015602090815260408083205460169092528220548291429183901580159061477957506000601354115b156147e4576000868152601660205260408120546147979085615314565b905060006127106301e1855883866013546147b291906152d3565b6147bc91906152d3565b6147c691906152f2565b6147d091906152f2565b92508290506147df848261537d565b935050505b9590945092505050565b816001600160a01b0316836001600160a01b031614156148505760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610c7d565b6001600160a01b03838116600081815260066020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6148c88484846142b0565b6148d484848484614bae565b6136115760405162461bcd60e51b8152600401610c7d90615721565b600060016148fd84612117565b6149079190615314565b60008381526008602052604090205490915080821461495a576001600160a01b03841660009081526007602090815260408083208584528252808320548484528184208190558352600890915290208190555b5060009182526008602090815260408084208490556001600160a01b039094168352600781528383209183525290812055565b60095460009061499f90600190615314565b6000838152600a6020526040812054600980549394509092849081106149c7576149c76155e7565b9060005260206000200154905080600983815481106149e8576149e86155e7565b6000918252602080832090910192909255828152600a90915260408082208490558582528120556009805480614a2057614a20615773565b6001900381819060005260206000200160009055905550505050565b6000614a4783612117565b6001600160a01b039093166000908152600760209081526040808320868452825280832085905593825260089052919091209190915550565b60006001600160e01b031982166380ac58cd60e01b1480614ab157506001600160e01b03198216635b5e139f60e01b145b80610e1d57506301ffc9a760e01b6001600160e01b0319831614610e1d565b61361184848484613e51565b6000614b31826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316614cac9092919063ffffffff16565b8051909150156110ae5780806020019051810190614b4f919061532b565b6110ae5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610c7d565b60006001600160a01b0384163b15614ca157604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290614bf2903390899088908890600401615789565b6020604051808303816000875af1925050508015614c2d575060408051601f3d908101601f19168201909252614c2a918101906157bc565b60015b614c87573d808015614c5b576040519150601f19603f3d011682016040523d82523d6000602084013e614c60565b606091505b508051614c7f5760405162461bcd60e51b8152600401610c7d90615721565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611207565b506001949350505050565b6060611207848460008585600080866001600160a01b03168587604051614cd391906157d9565b60006040518083038185875af1925050503d8060008114614d10576040519150601f19603f3d011682016040523d82523d6000602084013e614d15565b606091505b5091509150614d2687838387614d31565b979650505050505050565b60608315614d9d578251614d96576001600160a01b0385163b614d965760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610c7d565b5081611207565b6112078383815115614db25781518083602001fd5b8060405162461bcd60e51b8152600401610c7d9190614f6b565b828054614dd890615348565b90600052602060002090601f016020900481019282614dfa5760008555614e40565b82601f10614e1357805160ff1916838001178555614e40565b82800160010185558215614e40579182015b82811115614e40578251825591602001919060010190614e25565b50614e4c929150614ec4565b5090565b828054614e5c90615348565b90600052602060002090601f016020900481019282614e7e5760008555614e40565b82601f10614e975782800160ff19823516178555614e40565b82800160010185558215614e40579182015b82811115614e40578235825591602001919060010190614ea9565b5b80821115614e4c5760008155600101614ec5565b6001600160e01b031981168114611f5057600080fd5b600060208284031215614f0157600080fd5b8135614f0c81614ed9565b9392505050565b60005b83811015614f2e578181015183820152602001614f16565b838111156136115750506000910152565b60008151808452614f57816020860160208601614f13565b601f01601f19169290920160200192915050565b602081526000614f0c6020830184614f3f565b80356001600160a01b0381168114614f9557600080fd5b919050565b600060208284031215614fac57600080fd5b614f0c82614f7e565b600060208284031215614fc757600080fd5b5035919050565b60008060408385031215614fe157600080fd5b614fea83614f7e565b946020939093013593505050565b6000806040838503121561500b57600080fd5b50508035926020909101359150565b60008060006060848603121561502f57600080fd5b61503884614f7e565b925061504660208501614f7e565b9150604084013590509250925092565b60008060006060848603121561506b57600080fd5b505081359360208301359350604090920135919050565b8015158114611f5057600080fd5b600080604083850312156150a357600080fd5b6150ac83614f7e565b915060208301356150bc81615082565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff808411156150f8576150f86150c7565b604051601f8501601f19908116603f01168101908282118183101715615120576151206150c7565b8160405280935085815286868601111561513957600080fd5b858560208301376000602087830101525050509392505050565b60006020828403121561516557600080fd5b813567ffffffffffffffff81111561517c57600080fd5b8201601f8101841361518d57600080fd5b611207848235602084016150dd565b600080600080608085870312156151b257600080fd5b6151bb85614f7e565b93506151c960208601614f7e565b925060408501359150606085013567ffffffffffffffff8111156151ec57600080fd5b8501601f810187136151fd57600080fd5b61520c878235602084016150dd565b91505092959194509250565b6000806020838503121561522b57600080fd5b823567ffffffffffffffff8082111561524357600080fd5b818501915085601f83011261525757600080fd5b81358181111561526657600080fd5b86602082850101111561527857600080fd5b60209290920196919550909350505050565b6000806040838503121561529d57600080fd5b6152a683614f7e565b91506152b460208401614f7e565b90509250929050565b634e487b7160e01b600052601160045260246000fd5b60008160001904831182151516156152ed576152ed6152bd565b500290565b60008261530f57634e487b7160e01b600052601260045260246000fd5b500490565b600082821015615326576153266152bd565b500390565b60006020828403121561533d57600080fd5b8151614f0c81615082565b600181811c9082168061535c57607f821691505b6020821081141561290557634e487b7160e01b600052602260045260246000fd5b60008219821115615390576153906152bd565b500190565b600181815b808511156153d05781600019048211156153b6576153b66152bd565b808516156153c357918102915b93841c939080029061539a565b509250929050565b6000826153e757506001610e1d565b816153f457506000610e1d565b816001811461540a576002811461541457615430565b6001915050610e1d565b60ff841115615425576154256152bd565b50506001821b610e1d565b5060208310610133831016604e8410600b8410161715615453575081810a610e1d565b61545d8383615395565b8060001904821115615471576154716152bd565b029392505050565b6000614f0c83836153d8565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b6020808252601e908201527f66726f6e7420656e64207661756c7420646f6573206e6f742065786973740000604082015260600190565b602080825260139082015272119c9bdb9d08195b99081b9bdd081859191959606a1b604082015260600190565b60208082526014908201527315985d5b1d08191bd95cc81b9bdd08195e1a5cdd60621b604082015260600190565b6020808252600f908201526e36bab9ba103ab9b2903937baba32b960891b604082015260600190565b60006020828403121561559f57600080fd5b5051919050565b60208082526021908201527f5661756c7420646562742063616e277420626520756e646572206d696e4465626040820152601d60fa1b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b60208082526019908201527f5661756c74206973206e6f74206f776e656420627920796f7500000000000000604082015260600190565b600060208083526000845481600182811c91508083168061565657607f831692505b85831081141561567457634e487b7160e01b85526022600452602485fd5b87860183815260200181801561569157600181146156a2576156cd565b60ff198616825287820196506156cd565b60008b81526020902060005b868110156156c7578154848201529085019089016156ae565b83019750505b50949998505050505050505050565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b634e487b7160e01b600052603160045260246000fd5b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090613ada90830184614f3f565b6000602082840312156157ce57600080fd5b8151614f0c81614ed9565b600082516157eb818460208701614f13565b919091019291505056fea26469706673582212209cd2fad0217ea9c2d9e87e38e582ad46b394b173ccecfa37a23400b5e0359e6b64736f6c634300080b00330000000000000000000000002bdcf5e0aa88583d5a8c5d7993fd790eb26d58f9000000000000000000000000000000000000000000000000000000000000008200000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000dfa46478f9e5ea86d57387849598dbfb2e964b020000000000000000000000001f32b1c2345538c0c6f582fcb022739c4a194ebb00000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000019777374455448204f7074696d69736d204d4149205661756c74000000000000000000000000000000000000000000000000000000000000000000000000000008575354454f4d56540000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035697066733a2f2f516d567a7257716475413758533578547552367758516a544362473270424d393133694d54354e51504566376d520000000000000000000000
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061052f5760003560e01c80638da5cb5b116102af578063cc02ce2211610172578063e0df5b6f116100d9578063ece1373211610092578063ece1373214610b90578063f17336d714610ba3578063f1c91fa614610bac578063f2fde38b14610bb5578063f887ea4014610bc8578063ffc73da714610bdb57600080fd5b8063e0df5b6f14610b14578063e5f4dc9214610b27578063e985e9c514610b30578063eac989f814610b6c578063eb6a887d14610b74578063ec2e0ab314610b8757600080fd5b8063d0064c001161012b578063d0064c0014610a92578063d310f49b14610a9b578063d4a9b2c514610aae578063d73464cc14610ace578063d8dfeb4514610aee578063df98784614610b0157600080fd5b8063cc02ce2214610a46578063cd44db1b14610a59578063cdfedd6314610a63578063cea55f5714610a6e578063cf41d6f814610a77578063cf5f0f3c14610a7f57600080fd5b8063a57ff50311610216578063b3229a63116101cf578063b3229a63146109de578063b86f6aef146109f1578063b88d4fde14610a04578063c0d7865514610a17578063c71abb3214610a2a578063c87b56dd14610a3357600080fd5b8063a57ff50314610989578063a5e9883714610992578063a7c6a1001461099a578063a9c904b5146109a3578063b165ff0b146109b6578063b26025aa146109d657600080fd5b806397a41b8e1161026857806397a41b8e1461091f57806397ff37b91461093257806398c3f2db1461095257806398d721e01461095a578063a0be06f91461096d578063a22cb4651461097657600080fd5b80638da5cb5b146108c55780639035e4cb146108d657806393ee476a146108e957806394cd4ba7146108fc578063952cc86a1461090457806395d89b411461091757600080fd5b806342f371c6116103f75780636352211e1161035e57806370a082311161031757806370a0823114610868578063715018a61461087b578063728bbbb514610883578063767a7b051461088c57806385e290a31461089f57806386375994146108b257600080fd5b80636352211e146107f657806363b8817c146108095780636526941b1461081c578063687e8c171461082f5780636bc855cc14610842578063704b6c021461085557600080fd5b806356572ac0116103b057806356572ac01461078f578063570b2b84146107a25780635d12928b146107b55780635f84f302146107bd5780635ff09ac2146107d05780636234dc21146107e357600080fd5b806342f371c6146107145780634c19386c146107275780634f558e79146107305780634f6ccce7146107435780635357b9891461075657806354fd4d501461076957600080fd5b806321a78f681161049b5780633128ef27116104545780633128ef27146106a257806338536275146106b55780633db99177146106c857806340803854146106db57806342842e0e146106ee57806342966c681461070157600080fd5b806321a78f681461063757806323b872dd1461064a578063241a545a1461065d5780632df87573146106665780632f745c5914610686578063311f392a1461069957600080fd5b8063081812fc116104ed578063081812fc146105cc578063095ea7b3146105df5780630b78f9c0146105f257806311b4a8321461060557806318160ddd146106265780631c883e7b1461062e57600080fd5b806263750c1461053457806301ffc9a71461053e578063048c661d1461056657806304d7aef21461059157806306fdde03146105a457806307960532146105b9575b600080fd5b61053c610bee565b005b61055161054c366004614eef565b610e12565b60405190151581526020015b60405180910390f35b602354610579906001600160a01b031681565b6040516001600160a01b03909116815260200161055d565b602454610579906001600160a01b031681565b6105ac610e23565b60405161055d9190614f6b565b61053c6105c7366004614f9a565b610eb5565b6105796105da366004614fb5565b610f76565b61053c6105ed366004614fce565b610f9d565b61053c610600366004614ff8565b6110b3565b610618610613366004614fb5565b61115d565b60405190815260200161055d565b600954610618565b610618600f5481565b602554610579906001600160a01b031681565b61053c61065836600461501a565b61120f565b61061860135481565b610618610674366004614fb5565b60156020526000908152604090205481565b610618610694366004614fce565b611240565b610618601b5481565b61053c6106b0366004615056565b6112d6565b61053c6106c3366004614fb5565b6115f7565b61053c6106d6366004614fb5565b611634565b61053c6106e9366004614fb5565b6116d1565b61053c6106fc36600461501a565b6117d9565b61053c61070f366004614fb5565b6117f4565b600c54610579906001600160a01b031681565b61061860205481565b61055161073e366004614fb5565b6119b2565b610618610751366004614fb5565b6119bd565b610618610764366004615056565b611a50565b60265461077d90600160a01b900460ff1681565b60405160ff909116815260200161055d565b61061861079d366004614fb5565b611aff565b601d54610579906001600160a01b031681565b610618611bf0565b61053c6107cb366004614fb5565b611c59565b61053c6107de366004614fb5565b611c96565b61053c6107f1366004614fb5565b611e0c565b610579610804366004614fb5565b611e49565b61053c610817366004614f9a565b611ea9565b61053c61082a366004614fb5565b611f53565b61055161083d366004614ff8565b611f90565b61053c610850366004614f9a565b611fbf565b61053c610863366004614f9a565b61206b565b610618610876366004614f9a565b612117565b61053c61219d565b61061860105481565b61053c61089a366004614ff8565b6121af565b61053c6108ad366004614fb5565b612391565b61053c6108c0366004614fb5565b6124f7565b6027546001600160a01b0316610579565b6106186108e4366004614fb5565b612594565b6106186108f7366004614fb5565b61290b565b610618612972565b61053c610912366004614ff8565b6129e4565b6105ac612ec8565b61053c61092d366004615056565b612ed7565b610618610940366004614fb5565b60166020526000908152604090205481565b61061861329e565b61053c610968366004614f9a565b6132e8565b61061860185481565b61053c610984366004615090565b6133a0565b610618601e5481565b600f54610618565b610618600e5481565b61053c6109b1366004615153565b6133ab565b6106186109c4366004614f9a565b60216020526000908152604090205481565b6106186133f6565b6105516109ec366004614fb5565b613482565b6105516109ff366004614fb5565b61353c565b61053c610a1236600461519c565b6135df565b61053c610a25366004614f9a565b613617565b610618601f5481565b6105ac610a41366004614fb5565b613641565b61053c610a54366004614ff8565b6136e7565b6305f5e100610618565b6106186305f5e10081565b610618601a5481565b61053c61385c565b61053c610a8d366004615056565b6138f8565b61061860125481565b610618610aa9366004614fb5565b613a46565b610618610abc366004614fb5565b60146020526000908152604090205481565b610618610adc366004614fb5565b60176020526000908152604090205481565b601c54610579906001600160a01b031681565b610618610b0f366004614fb5565b613a52565b61053c610b22366004615218565b613ae4565b610618600d5481565b610551610b3e36600461528a565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205460ff1690565b6105ac613b29565b61053c610b82366004614fb5565b613bb7565b61061860195481565b61053c610b9e366004614ff8565b613c3a565b61061860115481565b61061860225481565b61053c610bc3366004614f9a565b613d35565b602654610579906001600160a01b031681565b61053c610be9366004614fb5565b613dab565b6025546001600160a01b0316331480610c1157506024546001600160a01b031633145b80610c35575033610c2a6027546001600160a01b031690565b6001600160a01b0316145b610c865760405162461bcd60e51b815260206004820152601f60248201527f4e6565647320746f2062652063616c6c6564206279206f70657261746f72730060448201526064015b60405180910390fd5b610c8e614012565b6000612710601854602254610ca391906152d3565b610cad91906152f2565b601d546025546022549293506001600160a01b039182169263a9059cbb9290911690610cda908590615314565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015610d25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d49919061532b565b50601d546024805460405163a9059cbb60e01b81526001600160a01b0391821660048201529182018490529091169063a9059cbb906044016020604051808303816000875af1158015610da0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc4919061532b565b507fc73fb14682b9d51008c1faff296cc9b351c0597de5e25b4ffa158f47f8254e4c602254604051610df891815260200190565b60405180910390a1506000602255610e106001600055565b565b6000610e1d8261406c565b92915050565b606060018054610e3290615348565b80601f0160208091040260200160405190810160405280929190818152602001828054610e5e90615348565b8015610eab5780601f10610e8057610100808354040283529160200191610eab565b820191906000526020600020905b815481529060010190602001808311610e8e57829003601f168201915b5050505050905090565b610ebd614091565b6001600160a01b038116610f215760405162461bcd60e51b815260206004820152602560248201527f4574687072696365736f757263652063616e6e6f74206265207a65726f206164604482015264647265737360d81b6064820152608401610c7d565b600c80546001600160a01b0319166001600160a01b0383169081179091556040519081527fc525e5fed1508c998d3f14bf52f933df1dd16dbf48e2944c426be721e268b755906020015b60405180910390a150565b6000610f81826140eb565b506000908152600560205260409020546001600160a01b031690565b6000610fa882611e49565b9050806001600160a01b0316836001600160a01b031614156110165760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610c7d565b336001600160a01b038216148061103257506110328133610b3e565b6110a45760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610c7d565b6110ae838361413b565b505050565b6110bb614091565b6127106110c8828461537d565b146111155760405162461bcd60e51b815260206004820152601a60248201527f736574466565733a206d75737420657175616c2031303030302e0000000000006044820152606401610c7d565b6018829055601981905560408051838152602081018390527f4d32f38862d5eb71edfefb7955873bd55920dc98159b6f53f8be62fbf0bebb4b91015b60405180910390a15050565b60008061116983613a46565b6000848152601460205260409020549091501580611185575080155b8061119657506111948361353c565b155b156111a45750600092915050565b6000838152601460205260408120546111bd90836141a9565b915050806111cf575060009392505050565b601f546111dd90600a615479565b6111e790826152f2565b90506000601a54826111f991906152f2565b905060115481116112075750805b949350505050565b6112193382614232565b6112355760405162461bcd60e51b8152600401610c7d90615485565b6110ae8383836142b0565b600061124b83612117565b82106112ad5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610c7d565b506001600160a01b03919091166000908152600760209081526040808320938352929052205490565b806112e081614421565b6112fc5760405162461bcd60e51b8152600401610c7d906154d2565b60008181526017602052604090205461271010801590611329575060008181526017602052604090205415155b6113455760405162461bcd60e51b8152600401610c7d90615509565b8361134f81614421565b61136b5760405162461bcd60e51b8152600401610c7d90615536565b6026546001600160a01b0316158061138d57506026546001600160a01b031633145b6113a95760405162461bcd60e51b8152600401610c7d90615564565b601d546040516370a0823160e01b815233600482015285916001600160a01b0316906370a0823190602401602060405180830381865afa1580156113f1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611415919061558d565b101561145b5760405162461bcd60e51b8152602060048201526015602482015274546f6b656e2062616c616e636520746f6f206c6f7760581b6044820152606401610c7d565b60006114668661290b565b9050848110156114c85760405162461bcd60e51b815260206004820152602760248201527f5661756c742064656274206c657373207468616e20616d6f756e7420746f20706044820152666179206261636b60c81b6064820152608401610c7d565b6011546114d58683615314565b1015806114e157508085145b6114fd5760405162461bcd60e51b8152600401610c7d906155a6565b600f54600085815260176020526040812054909161151c918890611a50565b90506115288683615314565b60008881526015602090815260408083209390935560149052205461154e908290615314565b60008881526014602052604080822092909255868152205461157190829061537d565b60008681526014602090815260409091209190915554611592908790615314565b602055601d546115ad906001600160a01b031633308961443e565b60408051888152602081018890529081018290527f31f96762af4051f367185773cc2f55bfb112a6c114b3407ded1f321a9eb199ac9060600160405180910390a150505050505050565b6115ff614091565b600d8190556040518181527fc0880963f3abc486dbb8b8f04ba4ce47c5b5cd3c59b6b7655f6011da0bf3365090602001610f6b565b61163c614091565b6101f481111561169c5760405162461bcd60e51b815260206004820152602560248201527f736574436c6f73696e674665653a2063616e6e6f74206265206d6f7265207468604482015264616e20352560d81b6064820152608401610c7d565b600f8190556040518181527fc1b83121984ef8e824a0babc08fc162077c0716a4dc307121f306e6dfb13806c90602001610f6b565b6116d9614091565b6116e281614421565b6117385760405162461bcd60e51b815260206004820152602160248201527f61646446726f6e74456e643a205661756c7420646f6573206e6f7420657869736044820152601d60fa1b6064820152608401610c7d565b600081815260176020526040902054156117945760405162461bcd60e51b815260206004820152601a60248201527f61646446726f6e74456e643a20616c72656164792061646465640000000000006044820152606401610c7d565b600081815260176020526040908190206127109055517f9d7c7013bbd38c45562efb3f7031f740c1f8b8886dbbf421142755ed68339f4c90610f6b9083815260200190565b6110ae838383604051806020016040528060008152506135df565b6024546001600160a01b0316331461184e5760405162461bcd60e51b815260206004820152601b60248201527f4e6565647320746f2062652063616c6c65642062792061646d696e00000000006044820152606401610c7d565b601d546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015611896573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118ba919061558d565b81106119085760405162461bcd60e51b815260206004820152601860248201527f6275726e3a2042616c616e6365206e6f7420656e6f75676800000000000000006044820152606401610c7d565b601d5460255460405163a9059cbb60e01b81526001600160a01b0391821660048201526024810184905291169063a9059cbb906044016020604051808303816000875af115801561195d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611981919061532b565b506040518181527fb1f67ade07cda330ac167f4fcc4c01b94fdfc04d401cf85e487f0a5b8b98e75f90602001610f6b565b6000610e1d82614421565b60006119c860095490565b8210611a2b5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610c7d565b60098281548110611a3e57611a3e6155e7565b90600052602060002001549050919050565b6000808215611aae5761271080611a6561329e565b611a6f91906152d3565b611a7991906152d3565b836305f5e100611a8988886152d3565b611a9391906152d3565b611a9d91906152d3565b611aa791906152f2565b9050611ae9565b612710611ab961329e565b611ac391906152d3565b6305f5e100611ad287876152d3565b611adc91906152d3565b611ae691906152f2565b90505b601e54611af690826152f2565b95945050505050565b6000818152601460205260408120541580611b205750611b1e8261353c565b155b15611b2d57506000919050565b6000611b3883613a46565b60008481526014602052604081205491925090611b5590836141a9565b9150506000601a5482611b6891906152f2565b905080611b7a57506000949350505050565b601154601f54611b8b90600a615479565b611b9590836152f2565b11611bd457601e54611ba561329e565b6103e8601b5485611bb691906152d3565b611bc091906152f2565b611bca91906152f2565b611af691906152f2565b601e54611bdf61329e565b6103e8601b5484611bb691906152d3565b600e54600090611c0181600161537d565b600e819055811115611c1257600080fd5b611c1c33826144a9565b604080518281523360208201527f8b6c1d05c678fa59695e26465a85918ce0fc63a88f74af53d1daef8f0a9c7804910160405180910390a1919050565b611c61614091565b60138190556040518181527f323264e3ca065ee856fe1b11204d8896a783bccf148380ac5d7362eb5c4c36a890602001610f6b565b80611ca081614421565b611cbc5760405162461bcd60e51b8152600401610c7d906154d2565b60008181526017602052604090205461271010801590611ce9575060008181526017602052604090205415155b611d055760405162461bcd60e51b8152600401610c7d90615509565b611d0d614091565b611d1682614421565b611d6e5760405162461bcd60e51b8152602060048201526024808201527f72656d6f766546726f6e74456e643a205661756c7420646f6573206e6f7420656044820152631e1a5cdd60e21b6064820152608401610c7d565b600082815260176020526040902054611dc95760405162461bcd60e51b815260206004820152601f60248201527f72656d6f766546726f6e74456e643a206e6f7420612066726f6e7420656e64006044820152606401610c7d565b60008281526017602052604080822091909155517f9b9f950fb3755096dbbe8b1519e73f7c6d1a0507f514fced444919530c00d719906111519084815260200190565b611e14614091565b60118190556040518181527f4533506fbaba6b18743358b6e6fb9392e8cb21757487b68d232a01b140bbec0190602001610f6b565b6000818152600360205260408120546001600160a01b031680610e1d5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610c7d565b611eb1614012565b6001600160a01b038116600090815260216020526040902054611f165760405162461bcd60e51b815260206004820152601c60248201527f446f6e2774206861766520616e797468696e6720666f7220796f752e000000006044820152606401610c7d565b6001600160a01b0380821660009081526021602052604081208054919055601c549091611f4591168383614624565b50611f506001600055565b50565b611f5b614091565b60128190556040518181527f1dd8f42ee4750a70f6662d1383372472422592497256d506437e35b3fa914d9b90602001610f6b565b6000806000611f9f85856141a9565b90925090506000611fb082846152f2565b600d5411159695505050505050565b611fc7614091565b6001600160a01b03811661201d5760405162461bcd60e51b815260206004820181905260248201527f5265666572656e636520416464726573732063616e6e6f74206265207a65726f6044820152606401610c7d565b602580546001600160a01b0319166001600160a01b0383169081179091556040519081527f8ed6553fa1e634b0152cd3539c572bee8c662e446820646d73a0e1b47776af9390602001610f6b565b612073614091565b6001600160a01b0381166120c95760405162461bcd60e51b815260206004820152601c60248201527f41646d696e20416464726573732063616e6e6f74206265207a65726f000000006044820152606401610c7d565b602480546001600160a01b0319166001600160a01b0383169081179091556040519081527ffce52dd00c7849a7f2602c1f189745238d6a2db16fabf54376ce24cc2fa3d57f90602001610f6b565b60006001600160a01b0382166121815760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610c7d565b506001600160a01b031660009081526004602052604090205490565b6121a5614091565b610e106000614654565b816121b981614421565b6121d55760405162461bcd60e51b8152600401610c7d90615536565b336121df82611e49565b6001600160a01b0316146122055760405162461bcd60e51b8152600401610c7d906155fd565b61220d614012565b6000838152601460205260409020548211156122795760405162461bcd60e51b815260206004820152602560248201527f5661756c7420646f6573206e6f74206861766520656e6f75676820636f6c6c616044820152641d195c985b60da1b6064820152608401610c7d565b600083815260146020526040812054612293908490615314565b905060006122a08561290b565b90508015612324576122b28282611f90565b6123245760405162461bcd60e51b815260206004820152603e60248201527f5769746864726177616c20776f756c6420707574207661756c742062656c6f7760448201527f206d696e696d756d20636f6c6c61746572616c2070657263656e7461676500006064820152608401610c7d565b6000858152601460205260409020829055601c5461234c906001600160a01b03163386614624565b60408051868152602081018690527f6c0ea3bea9dd66afa8f9d39d6eb93d833466190330813b42835efc650dca4cb9910160405180910390a150506110ae6001600055565b8061239b81614421565b6123b75760405162461bcd60e51b8152600401610c7d90615536565b336123c182611e49565b6001600160a01b0316146123e75760405162461bcd60e51b8152600401610c7d906155fd565b6123ef614012565b6123f882613a46565b156124455760405162461bcd60e51b815260206004820152601a60248201527f5661756c7420686173206f75747374616e64696e6720646562740000000000006044820152606401610c7d565b600082815260146020526040902054156124875761248761246583611e49565b600084815260146020526040902054601c546001600160a01b03169190614624565b612490826146a6565b600082815260146020908152604080832083905560158252808320839055601682528083209290925590518381527f4fe08624ee65b341c38ab9693d216b909d4ddee1bc8d3fe0fea14026c361b465910160405180910390a16124f36001600055565b5050565b6124ff614091565b6101f481111561255f5760405162461bcd60e51b815260206004820152602560248201527f7365744f70656e696e674665653a2063616e6e6f74206265206d6f7265207468604482015264616e20352560d81b6064820152608401610c7d565b60108190556040518181527fc4ced91ca77dc4287a54d9bd9b15c69b3aba262e30eba7c93301c48606019c9490602001610f6b565b6000816125a081614421565b6125bc5760405162461bcd60e51b8152600401610c7d90615536565b6023546001600160a01b031615806125de57506023546001600160a01b031633145b61262a5760405162461bcd60e51b815260206004820181905260248201527f627579207269736b792069732064697361626c656420666f72207075626c69636044820152606401610c7d565b60006126358461290b565b9050806126765760405162461bcd60e51b815260206004820152600f60248201526e05661756c742064656274206973203608c1b6044820152606401610c7d565b600084815260146020526040812054819061269190846141a9565b909250905060006126a282846152f2565b601b549091506126b382600a6152d3565b11156127185760405162461bcd60e51b815260206004820152602e60248201527f5661756c74206973206e6f742062656c6f77207269736b7920636f6c6c61746560448201526d72616c2070657263656e7461676560901b6064820152608401610c7d565b6000601f54600a6127299190615479565b600d5461273691906152d3565b61274090856152f2565b601f5461274e90600a615479565b61275890856152f2565b6127629190615314565b601d546040516370a0823160e01b815233600482015291925082916001600160a01b03909116906370a0823190602401602060405180830381865afa1580156127af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127d3919061558d565b101561282f5760405162461bcd60e51b815260206004820152602560248201527f4e6f7420656e6f756768206d616920746f2062757920746865207269736b79206044820152641d985d5b1d60da1b6064820152608401610c7d565b601d54612847906001600160a01b031633308461443e565b806020546128559190615314565b6020556000612862611bf0565b60008a8152601460205260408082205483835291205590506128848287615314565b600082815260156020818152604080842094909455601681528383204290558c8352601481528383208390559081528282209190915581518b815290810183905233818301526060810184905290517fa4cf7276e26bb566de2c7540759e85736eb743807343fd27e6e679b20e8814419181900360800190a1965050505050505b50919050565b600080600061291984614749565b915091508160225461292b919061537d565b60225560205461293c90839061537d565b602055601354156129595760008481526016602052604090204290555b6000938452601560205260409093208390555090919050565b601d546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa1580156129bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129df919061558d565b905090565b806129ee81614421565b612a0a5760405162461bcd60e51b8152600401610c7d906154d2565b60008181526017602052604090205461271010801590612a37575060008181526017602052604090205415155b612a535760405162461bcd60e51b8152600401610c7d90615509565b82612a5d81614421565b612a795760405162461bcd60e51b8152600401610c7d90615536565b6023546001600160a01b03161580612a9b57506023546001600160a01b031633145b612af25760405162461bcd60e51b815260206004820152602260248201527f6c69717569646174696f6e2069732064697361626c656420666f72207075626c604482015261696360f01b6064820152608401610c7d565b6000612afd8561290b565b600086815260146020526040812054919250908190612b1c90846141a9565b915091508260001415612b635760405162461bcd60e51b815260206004820152600f60248201526e05661756c742064656274206973203608c1b6044820152606401610c7d565b6000612b6f82846152f2565b9050600d548110612bdb5760405162461bcd60e51b815260206004820152603060248201527f5661756c74206973206e6f742062656c6f77206d696e696d756d20636f6c6c6160448201526f746572616c2070657263656e7461676560801b6064820152608401610c7d565b601b54612be982600a6152d3565b11612c365760405162461bcd60e51b815260206004820152601d60248201527f5661756c74206973206e6f742061626f7665206761696e20726174696f0000006044820152606401610c7d565b601f54612c4490600a615479565b612c4e90836152f2565b91506000601a5483612c6091906152f2565b90506011548111612c6e5750815b601d546040516370a0823160e01b815233600482015282916001600160a01b0316906370a0823190602401602060405180830381865afa158015612cb6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cda919061558d565b1015612d425760405162461bcd60e51b815260206004820152603160248201527f546f6b656e2062616c616e636520746f6f206c6f7720746f20706179206f6666604482015270081bdd5d1cdd185b991a5b99c81919589d607a1b6064820152608401610c7d565b80602054612d509190615314565b6020556000612d5e8a611aff565b9050612d6a8287615314565b60008b815260156020908152604080832093909355600f548c83526017909152918120549091612d9b918590611a50565b60008c815260146020526040902054909150612db8908290615314565b60008c815260146020526040808220929092558b81522054612ddb90829061537d565b60008b815260146020526040808220929092558c81522054612dfe908390615314565b60008c815260146020908152604080832093909355338252602190522054612e2790839061537d565b33600081815260216020526040902091909155601d54612e54916001600160a01b0390911690308661443e565b7f4d151d3a98b83151d51917640c221f8c8e3c054422ea1b48dcbbd57e3f4210d58b612e7f8d611e49565b604080519283526001600160a01b0390911660208301523390820152606081018590526080810184905260a0810183905260c00160405180910390a15050505050505050505050565b606060028054610e3290615348565b80612ee181614421565b612efd5760405162461bcd60e51b8152600401610c7d906154d2565b60008181526017602052604090205461271010801590612f2a575060008181526017602052604090205415155b612f465760405162461bcd60e51b8152600401610c7d90615509565b83612f5081614421565b612f6c5760405162461bcd60e51b8152600401610c7d90615536565b33612f7682611e49565b6001600160a01b031614612f9c5760405162461bcd60e51b8152600401610c7d906155fd565b612fa4614012565b60008411612ff45760405162461bcd60e51b815260206004820152601b60248201527f4d75737420626f72726f77206e6f6e2d7a65726f20616d6f756e7400000000006044820152606401610c7d565b612ffc612972565b8411156130635760405162461bcd60e51b815260206004820152602f60248201527f626f72726f77546f6b656e3a2043616e6e6f74206d696e74206f76657220617660448201526e30b4b630b136329039bab838363c9760891b6064820152608401610c7d565b60008461306f8761290b565b613079919061537d565b90506012548111156130d85760405162461bcd60e51b815260206004820152602260248201527f626f72726f77546f6b656e3a206d6178206c6f616e2063617020726561636865604482015261321760f11b6064820152608401610c7d565b6130e186613a46565b81116130ec57600080fd5b6000868152601460205260409020546131059082611f90565b6131775760405162461bcd60e51b815260206004820152603a60248201527f426f72726f7720776f756c6420707574207661756c742062656c6f77206d696e60448201527f696d756d20636f6c6c61746572616c2070657263656e746167650000000000006064820152608401610c7d565b6011548561318488613a46565b61318e919061537d565b10156131ac5760405162461bcd60e51b8152600401610c7d906155a6565b600086815260156020908152604080832084905560105487845260179092528220546131da91908490611a50565b6000888152601460205260409020549091506131f7908290615314565b60008881526014602052604080822092909255868152205461321a90829061537d565b600086815260146020526040902055601d54613240906001600160a01b03163388614624565b8560205461324e919061537d565b6020908155604080518981529182018890527f3e08df88d8e28f37df9bf227d3142ac506a364403445661a60891a49ed6792ca910160405180910390a150506132976001600055565b5050505050565b600c54604080516350d25bcd60e01b815290516000926001600160a01b0316916350d25bcd9160048083019260209291908290030181865afa1580156129bb573d6000803e3d6000fd5b6132f0614091565b6001600160a01b0381166133525760405162461bcd60e51b8152602060048201526024808201527f53746162696c697479506f6f6c2063616e6e6f74206265207a65726f206164646044820152637265737360e01b6064820152608401610c7d565b602380546001600160a01b0319166001600160a01b0383169081179091556040519081527f0644c4f539d7f787d2287c12d9425e80aefc8bdae99c70af4ca66fb0742577e890602001610f6b565b6124f33383836147ee565b6133b3614091565b80516133c6906028906020840190614dcc565b507f0d82453dd4ad18b5ce3db08c34a39340ad2bf15046a7d0e86aa075483eb121d881604051610f6b9190614f6b565b601c546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa15801561343f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613463919061558d565b601e5461346e61329e565b61347891906152d3565b6129df91906152d3565b60008161348e81614421565b6134aa5760405162461bcd60e51b8152600401610c7d90615536565b60006134b584613a46565b60008581526014602052604090205490915015806134d1575080155b156134e0576000925050612905565b60008481526014602052604081205481906134fb90846141a9565b9092509050600061350c82846152f2565b601b5490915061351d82600a6152d3565b1161352f576001955050505050612905565b6000955050505050612905565b60008161354881614421565b6135645760405162461bcd60e51b8152600401610c7d90615536565b600061356f84613a46565b600085815260146020526040902054909150158061358b575080155b1561359a576000925050612905565b60008481526014602052604081205481906135b590846141a9565b909250905060006135c682846152f2565b9050600d5481101561352f576001955050505050612905565b6135e93383614232565b6136055760405162461bcd60e51b8152600401610c7d90615485565b613611848484846148bd565b50505050565b61361f614091565b602680546001600160a01b0319166001600160a01b0392909216919091179055565b606061364c82614421565b61365557600080fd5b600b805461366290615348565b80601f016020809104026020016040519081016040528092919081815260200182805461368e90615348565b80156136db5780601f106136b0576101008083540402835291602001916136db565b820191906000526020600020905b8154815290600101906020018083116136be57829003601f168201915b50505050509050919050565b816136f181614421565b61370d5760405162461bcd60e51b8152600401610c7d906154d2565b6000818152601760205260409020546127101080159061373a575060008181526017602052604090205415155b6137565760405162461bcd60e51b8152600401610c7d90615509565b8261376081614421565b61377c5760405162461bcd60e51b8152600401610c7d90615536565b3361378682611e49565b6001600160a01b0316146137ac5760405162461bcd60e51b8152600401610c7d906155fd565b6000831180156137be57506127108311155b61380a5760405162461bcd60e51b815260206004820152601b60248201527f75706461746546726f6e74456e643a2063616e6e6f74206265203000000000006044820152606401610c7d565b60008481526017602090815260409182902085905581518681529081018590527fbfdd5aecf44aa804bf11f070a41765d280dab82adbfd1c55e1e85b7d5b7920b491015b60405180910390a150505050565b613864614012565b336000908152602160205260409020546138c05760405162461bcd60e51b815260206004820152601c60248201527f446f6e2774206861766520616e797468696e6720666f7220796f752e000000006044820152606401610c7d565b3360008181526021602052604081208054919055601c5490916138ed916001600160a01b03169083614624565b50610e106001600055565b8061390281614421565b61391e5760405162461bcd60e51b8152600401610c7d906154d2565b6000818152601760205260409020546127101080159061394b575060008181526017602052604090205415155b6139675760405162461bcd60e51b8152600401610c7d90615509565b8361397181614421565b61398d5760405162461bcd60e51b8152600401610c7d90615536565b6026546001600160a01b031615806139af57506026546001600160a01b031633145b6139cb5760405162461bcd60e51b8152600401610c7d90615564565b42841015613a265760405162461bcd60e51b815260206004820152602260248201527f7061796261636b546f6b656e416c6c3a20646561646c696e6520657870697265604482015261321760f11b6064820152608401610c7d565b6000613a318661290b565b9050613a3e8682866112d6565b505050505050565b60008061120783614749565b600081613a5e81614421565b613a7a5760405162461bcd60e51b8152600401610c7d90615536565b6000613a8584613a46565b6000858152601460205260409020549091501580613aa1575080155b15613ab0576000925050612905565b6000848152601460205260408120548190613acb90846141a9565b9092509050613ada81836152f2565b9695505050505050565b613aec614091565b613af8600b8383614e50565b507ffda45751019c07e08a3ebf7d73a4aea1a6c36bee12d87089096012911a756ab5600b6040516111519190615634565b600b8054613b3690615348565b80601f0160208091040260200160405190810160405280929190818152602001828054613b6290615348565b8015613baf5780601f10613b8457610100808354040283529160200191613baf565b820191906000526020600020905b815481529060010190602001808311613b9257829003601f168201915b505050505081565b613bbf614091565b80613c055760405162461bcd60e51b815260206004820152601660248201527504465627420526174696f2063616e6e6f7420626520360541b6044820152606401610c7d565b601a8190556040518181527f199e93b2fae27b389e2d09761871573f60121b8521be96b8f28c83bf94846ac290602001610f6b565b81613c4481614421565b613c605760405162461bcd60e51b8152600401610c7d90615536565b6026546001600160a01b03161580613c8257506026546001600160a01b031633145b613c9e5760405162461bcd60e51b8152600401610c7d90615564565b600083815260146020526040812054613cb890849061537d565b600085815260146020526040902054909150811015613cd657600080fd5b6000848152601460205260409020819055601c54613cff906001600160a01b031633308661443e565b60408051858152602081018590527f52c4e7127ec34e8fc95f09ce2d06b4f00acca12ccbcdfb246ef67ee6aefe068d910161384e565b613d3d614091565b6001600160a01b038116613da25760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610c7d565b611f5081614654565b613db3614091565b6103e8811015613e1c5760405162461bcd60e51b815260206004820152602e60248201527f6761696e526174696f2063616e6e6f74206265206c657373207468616e206f7260448201526d020657175616c20746f20313030360941b6064820152608401610c7d565b601b8190556040518181527fb6d384ad48d9c5c042c81fa0f88d8061ef87b38475101d6aa5f9ae5a8274a64e90602001610f6b565b613e5d84848484613f8a565b6001811115613ecc5760405162461bcd60e51b815260206004820152603560248201527f455243373231456e756d657261626c653a20636f6e7365637574697665207472604482015274185b9cd9995c9cc81b9bdd081cdd5c1c1bdc9d1959605a1b6064820152608401610c7d565b816001600160a01b038516613f2857613f2381600980546000838152600a60205260408120829055600182018355919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0155565b613f4b565b836001600160a01b0316856001600160a01b031614613f4b57613f4b85826148f0565b6001600160a01b038416613f6757613f628161498d565b613297565b846001600160a01b0316846001600160a01b031614613297576132978482614a3c565b6001811115613611576001600160a01b03841615613fd0576001600160a01b03841660009081526004602052604081208054839290613fca908490615314565b90915550505b6001600160a01b03831615613611576001600160a01b0383166000908152600460205260408120805483929061400790849061537d565b909155505050505050565b600260005414156140655760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610c7d565b6002600055565b60006001600160e01b0319821663780e9d6360e01b1480610e1d5750610e1d82614a80565b6027546001600160a01b03163314610e105760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c7d565b6140f481614421565b611f505760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610c7d565b600081815260056020526040902080546001600160a01b0319166001600160a01b038416908117909155819061417082611e49565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000806141b461329e565b6141bd57600080fd5b6000601e546141ca61329e565b6141d490876152d3565b6141de91906152d3565b9050848110156141ed57600080fd5b60006141fd6305f5e100866152d3565b90508481101561420c57600080fd5b60006142198360646152d3565b905082811161422757600080fd5b969095509350505050565b60008061423e83611e49565b9050806001600160a01b0316846001600160a01b0316148061428557506001600160a01b0380821660009081526006602090815260408083209388168352929052205460ff165b806112075750836001600160a01b031661429e84610f76565b6001600160a01b031614949350505050565b826001600160a01b03166142c382611e49565b6001600160a01b0316146142e95760405162461bcd60e51b8152600401610c7d906156dc565b6001600160a01b03821661434b5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610c7d565b6143588383836001614ad0565b826001600160a01b031661436b82611e49565b6001600160a01b0316146143915760405162461bcd60e51b8152600401610c7d906156dc565b600081815260056020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260048552838620805460001901905590871680865283862080546001019055868652600390945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000908152600360205260409020546001600160a01b0316151590565b6040516001600160a01b03808516602483015283166044820152606481018290526136119085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614adc565b6001600160a01b0382166144ff5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610c7d565b61450881614421565b156145555760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610c7d565b614563600083836001614ad0565b61456c81614421565b156145b95760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610c7d565b6001600160a01b038216600081815260046020908152604080832080546001019055848352600390915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6040516001600160a01b0383166024820152604481018290526110ae90849063a9059cbb60e01b90606401614472565b602780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006146b182611e49565b90506146c1816000846001614ad0565b6146ca82611e49565b600083815260056020908152604080832080546001600160a01b03199081169091556001600160a01b0385168085526004845282852080546000190190558785526003909352818420805490911690555192935084927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b60008181526015602090815260408083205460169092528220548291429183901580159061477957506000601354115b156147e4576000868152601660205260408120546147979085615314565b905060006127106301e1855883866013546147b291906152d3565b6147bc91906152d3565b6147c691906152f2565b6147d091906152f2565b92508290506147df848261537d565b935050505b9590945092505050565b816001600160a01b0316836001600160a01b031614156148505760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610c7d565b6001600160a01b03838116600081815260066020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6148c88484846142b0565b6148d484848484614bae565b6136115760405162461bcd60e51b8152600401610c7d90615721565b600060016148fd84612117565b6149079190615314565b60008381526008602052604090205490915080821461495a576001600160a01b03841660009081526007602090815260408083208584528252808320548484528184208190558352600890915290208190555b5060009182526008602090815260408084208490556001600160a01b039094168352600781528383209183525290812055565b60095460009061499f90600190615314565b6000838152600a6020526040812054600980549394509092849081106149c7576149c76155e7565b9060005260206000200154905080600983815481106149e8576149e86155e7565b6000918252602080832090910192909255828152600a90915260408082208490558582528120556009805480614a2057614a20615773565b6001900381819060005260206000200160009055905550505050565b6000614a4783612117565b6001600160a01b039093166000908152600760209081526040808320868452825280832085905593825260089052919091209190915550565b60006001600160e01b031982166380ac58cd60e01b1480614ab157506001600160e01b03198216635b5e139f60e01b145b80610e1d57506301ffc9a760e01b6001600160e01b0319831614610e1d565b61361184848484613e51565b6000614b31826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316614cac9092919063ffffffff16565b8051909150156110ae5780806020019051810190614b4f919061532b565b6110ae5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610c7d565b60006001600160a01b0384163b15614ca157604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290614bf2903390899088908890600401615789565b6020604051808303816000875af1925050508015614c2d575060408051601f3d908101601f19168201909252614c2a918101906157bc565b60015b614c87573d808015614c5b576040519150601f19603f3d011682016040523d82523d6000602084013e614c60565b606091505b508051614c7f5760405162461bcd60e51b8152600401610c7d90615721565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611207565b506001949350505050565b6060611207848460008585600080866001600160a01b03168587604051614cd391906157d9565b60006040518083038185875af1925050503d8060008114614d10576040519150601f19603f3d011682016040523d82523d6000602084013e614d15565b606091505b5091509150614d2687838387614d31565b979650505050505050565b60608315614d9d578251614d96576001600160a01b0385163b614d965760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610c7d565b5081611207565b6112078383815115614db25781518083602001fd5b8060405162461bcd60e51b8152600401610c7d9190614f6b565b828054614dd890615348565b90600052602060002090601f016020900481019282614dfa5760008555614e40565b82601f10614e1357805160ff1916838001178555614e40565b82800160010185558215614e40579182015b82811115614e40578251825591602001919060010190614e25565b50614e4c929150614ec4565b5090565b828054614e5c90615348565b90600052602060002090601f016020900481019282614e7e5760008555614e40565b82601f10614e975782800160ff19823516178555614e40565b82800160010185558215614e40579182015b82811115614e40578235825591602001919060010190614ea9565b5b80821115614e4c5760008155600101614ec5565b6001600160e01b031981168114611f5057600080fd5b600060208284031215614f0157600080fd5b8135614f0c81614ed9565b9392505050565b60005b83811015614f2e578181015183820152602001614f16565b838111156136115750506000910152565b60008151808452614f57816020860160208601614f13565b601f01601f19169290920160200192915050565b602081526000614f0c6020830184614f3f565b80356001600160a01b0381168114614f9557600080fd5b919050565b600060208284031215614fac57600080fd5b614f0c82614f7e565b600060208284031215614fc757600080fd5b5035919050565b60008060408385031215614fe157600080fd5b614fea83614f7e565b946020939093013593505050565b6000806040838503121561500b57600080fd5b50508035926020909101359150565b60008060006060848603121561502f57600080fd5b61503884614f7e565b925061504660208501614f7e565b9150604084013590509250925092565b60008060006060848603121561506b57600080fd5b505081359360208301359350604090920135919050565b8015158114611f5057600080fd5b600080604083850312156150a357600080fd5b6150ac83614f7e565b915060208301356150bc81615082565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff808411156150f8576150f86150c7565b604051601f8501601f19908116603f01168101908282118183101715615120576151206150c7565b8160405280935085815286868601111561513957600080fd5b858560208301376000602087830101525050509392505050565b60006020828403121561516557600080fd5b813567ffffffffffffffff81111561517c57600080fd5b8201601f8101841361518d57600080fd5b611207848235602084016150dd565b600080600080608085870312156151b257600080fd5b6151bb85614f7e565b93506151c960208601614f7e565b925060408501359150606085013567ffffffffffffffff8111156151ec57600080fd5b8501601f810187136151fd57600080fd5b61520c878235602084016150dd565b91505092959194509250565b6000806020838503121561522b57600080fd5b823567ffffffffffffffff8082111561524357600080fd5b818501915085601f83011261525757600080fd5b81358181111561526657600080fd5b86602082850101111561527857600080fd5b60209290920196919550909350505050565b6000806040838503121561529d57600080fd5b6152a683614f7e565b91506152b460208401614f7e565b90509250929050565b634e487b7160e01b600052601160045260246000fd5b60008160001904831182151516156152ed576152ed6152bd565b500290565b60008261530f57634e487b7160e01b600052601260045260246000fd5b500490565b600082821015615326576153266152bd565b500390565b60006020828403121561533d57600080fd5b8151614f0c81615082565b600181811c9082168061535c57607f821691505b6020821081141561290557634e487b7160e01b600052602260045260246000fd5b60008219821115615390576153906152bd565b500190565b600181815b808511156153d05781600019048211156153b6576153b66152bd565b808516156153c357918102915b93841c939080029061539a565b509250929050565b6000826153e757506001610e1d565b816153f457506000610e1d565b816001811461540a576002811461541457615430565b6001915050610e1d565b60ff841115615425576154256152bd565b50506001821b610e1d565b5060208310610133831016604e8410600b8410161715615453575081810a610e1d565b61545d8383615395565b8060001904821115615471576154716152bd565b029392505050565b6000614f0c83836153d8565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b6020808252601e908201527f66726f6e7420656e64207661756c7420646f6573206e6f742065786973740000604082015260600190565b602080825260139082015272119c9bdb9d08195b99081b9bdd081859191959606a1b604082015260600190565b60208082526014908201527315985d5b1d08191bd95cc81b9bdd08195e1a5cdd60621b604082015260600190565b6020808252600f908201526e36bab9ba103ab9b2903937baba32b960891b604082015260600190565b60006020828403121561559f57600080fd5b5051919050565b60208082526021908201527f5661756c7420646562742063616e277420626520756e646572206d696e4465626040820152601d60fa1b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b60208082526019908201527f5661756c74206973206e6f74206f776e656420627920796f7500000000000000604082015260600190565b600060208083526000845481600182811c91508083168061565657607f831692505b85831081141561567457634e487b7160e01b85526022600452602485fd5b87860183815260200181801561569157600181146156a2576156cd565b60ff198616825287820196506156cd565b60008b81526020902060005b868110156156c7578154848201529085019089016156ae565b83019750505b50949998505050505050505050565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b634e487b7160e01b600052603160045260246000fd5b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090613ada90830184614f3f565b6000602082840312156157ce57600080fd5b8151614f0c81614ed9565b600082516157eb818460208701614f13565b919091019291505056fea26469706673582212209cd2fad0217ea9c2d9e87e38e582ad46b394b173ccecfa37a23400b5e0359e6b64736f6c634300080b0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000002bdcf5e0aa88583d5a8c5d7993fd790eb26d58f9000000000000000000000000000000000000000000000000000000000000008200000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000dfa46478f9e5ea86d57387849598dbfb2e964b020000000000000000000000001f32b1c2345538c0c6f582fcb022739c4a194ebb00000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000019777374455448204f7074696d69736d204d4149205661756c74000000000000000000000000000000000000000000000000000000000000000000000000000008575354454f4d56540000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035697066733a2f2f516d567a7257716475413758533578547552367758516a544362473270424d393133694d54354e51504566376d520000000000000000000000
-----Decoded View---------------
Arg [0] : ethPriceSourceAddress (address): 0x2BDCF5E0Aa88583D5a8C5d7993FD790eB26D58F9
Arg [1] : minimumCollateralPercentage (uint256): 130
Arg [2] : name (string): wstETH Optimism MAI Vault
Arg [3] : symbol (string): WSTEOMVT
Arg [4] : _mai (address): 0xdFA46478F9e5EA86d57387849598dbFB2e964b02
Arg [5] : _collateral (address): 0x1F32b1c2345538c0c6f582fCB022739c4A194Ebb
Arg [6] : baseURI (string): ipfs://QmVzrWqduA7XS5xTuR6wXQjTCbG2pBM913iMT5NQPEf7mR
-----Encoded View---------------
14 Constructor Arguments found :
Arg [0] : 0000000000000000000000002bdcf5e0aa88583d5a8c5d7993fd790eb26d58f9
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000082
Arg [2] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000120
Arg [4] : 000000000000000000000000dfa46478f9e5ea86d57387849598dbfb2e964b02
Arg [5] : 0000000000000000000000001f32b1c2345538c0c6f582fcb022739c4a194ebb
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000160
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000019
Arg [8] : 777374455448204f7074696d69736d204d4149205661756c7400000000000000
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000008
Arg [10] : 575354454f4d5654000000000000000000000000000000000000000000000000
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000035
Arg [12] : 697066733a2f2f516d567a7257716475413758533578547552367758516a5443
Arg [13] : 62473270424d393133694d54354e51504566376d520000000000000000000000
Deployed Bytecode Sourcemap
118748:10746:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;128046:332;;;:::i;:::-;;60558:171;;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;60558:171:0;;;;;;;;89205:28;;;;;-1:-1:-1;;;;;89205:28:0;;;;;;-1:-1:-1;;;;;756:32:1;;;738:51;;726:2;711:18;89205:28:0;592:203:1;89240:18:0;;;;;-1:-1:-1;;;;;89240:18:0;;;37187:100;;;:::i;:::-;;;;;;;:::i;122173:331::-;;;;;;:::i;:::-;;:::i;38699:171::-;;;;;;:::i;:::-;;:::i;38217:416::-;;;;;;:::i;:::-;;:::i;123315:244::-;;;;;;:::i;:::-;;:::i;106050:799::-;;;;;;:::i;:::-;;:::i;:::-;;;2918:25:1;;;2906:2;2891:18;106050:799:0;2772:177:1;54853:113:0;54941:10;:17;54853:113;;88322:25;;;;;;89265:18;;;;;-1:-1:-1;;;;;89265:18:0;;;39399:335;;;;;;:::i;:::-;;:::i;88501:17::-;;;;;;88584:55;;;;;;:::i;:::-;;;;;;;;;;;;;;54521:256;;;;;;:::i;:::-;;:::i;88905:24::-;;;;;;103879:1151;;;;;;:::i;:::-;;:::i;123737:258::-;;;;;;:::i;:::-;;:::i;126154:277::-;;;;;;:::i;:::-;;:::i;126645:303::-;;;;;;:::i;:::-;;:::i;39805:185::-;;;;;;:::i;:::-;;:::i;128874:250::-;;;;;;:::i;:::-;;:::i;88189:34::-;;;;;-1:-1:-1;;;;;88189:34:0;;;89086:28;;;;;;92534:104;;;;;;:::i;:::-;;:::i;55043:233::-;;;;;;:::i;:::-;;:::i;97936:533::-;;;;;;:::i;:::-;;:::i;89318:24::-;;;;;-1:-1:-1;;;89318:24:0;;;;;;;;;4007:4:1;3995:17;;;3977:36;;3965:2;3950:18;89318:24:0;3835:184:1;107083:896:0;;;;;;:::i;:::-;;:::i;88968:16::-;;;;;-1:-1:-1;;;;;88968:16:0;;;98585:259;;;:::i;128502:123::-;;;;;;:::i;:::-;;:::i;127660:325::-;;;;;;:::i;:::-;;:::i;124146:219::-;;;;;;:::i;:::-;;:::i;36897:223::-;;;;;;:::i;:::-;;:::i;105584:249::-;;;;;;:::i;:::-;;:::i;124532:219::-;;;;;;:::i;:::-;;:::i;97109:429::-;;;;;;:::i;:::-;;:::i;124952:183::-;;;;;;:::i;:::-;;:::i;125341:::-;;;;;;:::i;:::-;;:::i;36628:207::-;;;;;;:::i;:::-;;:::i;117736:103::-;;;:::i;88354:25::-;;;;;;100626:775;;;;;;:::i;:::-;;:::i;99022:578::-;;;;;;:::i;:::-;;:::i;125701:277::-;;;;;;:::i;:::-;;:::i;117088:87::-;117161:6;;-1:-1:-1;;;;;117161:6:0;117088:87;;113771:2071;;;;;;:::i;:::-;;:::i;95283:454::-;;;;;;:::i;:::-;;:::i;92186:110::-;;;:::i;110962:2349::-;;;;;;:::i;:::-;;:::i;37356:104::-;;;:::i;101762:1365::-;;;;;;:::i;:::-;;:::i;88648:47::-;;;;;;:::i;:::-;;;;;;;;;;;;;;93701:114;;;:::i;122741:231::-;;;;;;:::i;:::-;;:::i;88754:23::-;;;;;;38942:155;;;;;;:::i;:::-;;:::i;88993:43::-;;;;;;93181:93;93256:10;;93181:93;;88284:25;;;;;;120927:149;;;;;;:::i;:::-;;:::i;89123:44::-;;;;;;:::i;:::-;;;;;;;;;;;;;;92788:252;;;:::i;109861:702::-;;;;;;:::i;:::-;;:::i;108909:753::-;;;;;;:::i;:::-;;:::i;40061:322::-;;;;;;:::i;:::-;;:::i;129403:88::-;;;;;;:::i;:::-;;:::i;89045:34::-;;;;;;60883:147;;;;;;:::i;:::-;;:::i;127217:311::-;;;;;;:::i;:::-;;:::i;93428:95::-;88483:3;93428:95;;88448:38;;88483:3;88448:38;;88874:24;;;;;;105146:266;;;:::i;103135:405::-;;;;;;:::i;:::-;;:::i;88417:22::-;;;;;;94926:151;;;;;;:::i;:::-;;:::i;88527:50::-;;;;;;:::i;:::-;;;;;;;;;;;;;;88702:43;;;;;;:::i;:::-;;;;;;;;;;;;;;88938:23;;;;;-1:-1:-1;;;;;88938:23:0;;;108129:585;;;;;;:::i;:::-;;:::i;129268:127::-;;;;;;:::i;:::-;;:::i;88232:43::-;;;;;;39168:164;;;;;;:::i;:::-;-1:-1:-1;;;;;39289:25:0;;;39265:4;39289:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;39168:164;60313:17;;;:::i;121698:206::-;;;;;;:::i;:::-;;:::i;88814:21::-;;;;;;99878:454;;;;;;:::i;:::-;;:::i;88388:22::-;;;;;;89174;;;;;;117994:201;;;;;;:::i;:::-;;:::i;89290:21::-;;;;;-1:-1:-1;;;;;89290:21:0;;;121273:233;;;;;;:::i;:::-;;:::i;128046:332::-;120538:3;;-1:-1:-1;;;;;120538:3:0;120545:10;120538:17;;:38;;-1:-1:-1;120559:3:0;;-1:-1:-1;;;;;120559:3:0;120566:10;120559:17;120538:38;:63;;;-1:-1:-1;120591:10:0;120580:7;117161:6;;-1:-1:-1;;;;;117161:6:0;;117088:87;120580:7;-1:-1:-1;;;;;120580:21:0;;120538:63;120530:107;;;;-1:-1:-1;;;120530:107:0;;7650:2:1;120530:107:0;;;7632:21:1;7689:2;7669:18;;;7662:30;7728:33;7708:18;;;7701:61;7779:18;;120530:107:0;;;;;;;;;63388:21:::1;:19;:21::i;:::-;128123:15:::2;88093:5;128149:8;;128141:7;;:16;;;;:::i;:::-;:31;;;;:::i;:::-;128206:3;::::0;128219::::2;::::0;128225:7:::2;::::0;128123:49;;-1:-1:-1;;;;;;128206:3:0;;::::2;::::0;:12:::2;::::0;128219:3;;::::2;::::0;128225:15:::2;::::0;128123:49;;128225:15:::2;:::i;:::-;128206:37;::::0;-1:-1:-1;;;;;;128206:37:0::2;::::0;;;;;;-1:-1:-1;;;;;8657:32:1;;;128206:37:0::2;::::0;::::2;8639:51:1::0;8706:18;;;8699:34;8612:18;;128206:37:0::2;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;128281:3:0::2;::::0;128294::::2;::::0;;128281:26:::2;::::0;-1:-1:-1;;;128281:26:0;;-1:-1:-1;;;;;128294:3:0;;::::2;128281:26;::::0;::::2;8639:51:1::0;8706:18;;;8699:34;;;128281:3:0;;::::2;::::0;:12:::2;::::0;8612:18:1;;128281:26:0::2;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;128323:25;128340:7;;128323:25;;;;2918::1::0;;2906:2;2891:18;;2772:177;128323:25:0::2;;;;;;;;-1:-1:-1::0;128369:1:0::2;128359:7;:11:::0;63432:20:::1;62826:1:::0;63952:7;:22;63769:213;63432:20:::1;128046:332::o:0;60558:171::-;60661:4;60685:36;60709:11;60685:23;:36::i;:::-;60678:43;60558:171;-1:-1:-1;;60558:171:0:o;37187:100::-;37241:13;37274:5;37267:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37187:100;:::o;122173:331::-;116974:13;:11;:13::i;:::-;-1:-1:-1;;;;;122295:35:0;::::1;122287:86;;;::::0;-1:-1:-1;;;122287:86:0;;9581:2:1;122287:86:0::1;::::0;::::1;9563:21:1::0;9620:2;9600:18;;;9593:30;9659:34;9639:18;;;9632:62;-1:-1:-1;;;9710:18:1;;;9703:35;9755:19;;122287:86:0::1;9379:401:1::0;122287:86:0::1;122384:14;:52:::0;;-1:-1:-1;;;;;;122384:52:0::1;-1:-1:-1::0;;;;;122384:52:0;::::1;::::0;;::::1;::::0;;;122452:44:::1;::::0;738:51:1;;;122452:44:0::1;::::0;726:2:1;711:18;122452:44:0::1;;;;;;;;122173:331:::0;:::o;38699:171::-;38775:7;38795:23;38810:7;38795:14;:23::i;:::-;-1:-1:-1;38838:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;38838:24:0;;38699:171::o;38217:416::-;38298:13;38314:23;38329:7;38314:14;:23::i;:::-;38298:39;;38362:5;-1:-1:-1;;;;;38356:11:0;:2;-1:-1:-1;;;;;38356:11:0;;;38348:57;;;;-1:-1:-1;;;38348:57:0;;9987:2:1;38348:57:0;;;9969:21:1;10026:2;10006:18;;;9999:30;10065:34;10045:18;;;10038:62;-1:-1:-1;;;10116:18:1;;;10109:31;10157:19;;38348:57:0;9785:397:1;38348:57:0;16595:10;-1:-1:-1;;;;;38440:21:0;;;;:62;;-1:-1:-1;38465:37:0;38482:5;16595:10;39168:164;:::i;38465:37::-;38418:173;;;;-1:-1:-1;;;38418:173:0;;10389:2:1;38418:173:0;;;10371:21:1;10428:2;10408:18;;;10401:30;10467:34;10447:18;;;10440:62;10538:31;10518:18;;;10511:59;10587:19;;38418:173:0;10187:425:1;38418:173:0;38604:21;38613:2;38617:7;38604:8;:21::i;:::-;38287:346;38217:416;;:::o;123315:244::-;116974:13;:11;:13::i;:::-;88093:5:::1;123401:11;123408:4:::0;123401:6;:11:::1;:::i;:::-;123400:27;123392:66;;;::::0;-1:-1:-1;;;123392:66:0;;10952:2:1;123392:66:0::1;::::0;::::1;10934:21:1::0;10991:2;10971:18;;;10964:30;11030:28;11010:18;;;11003:56;11076:18;;123392:66:0::1;10750:350:1::0;123392:66:0::1;123469:8;:15:::0;;;123495:6:::1;:11:::0;;;123522:29:::1;::::0;;11279:25:1;;;11335:2;11320:18;;11313:34;;;123522:29:0::1;::::0;11252:18:1;123522:29:0::1;;;;;;;;123315:244:::0;;:::o;106050:799::-;106107:7;106127:20;106150:18;106160:7;106150:9;:18::i;:::-;106199:24;;;;:15;:24;;;;;;106127:41;;-1:-1:-1;106199:29:0;;:63;;-1:-1:-1;106245:17:0;;106199:63;:106;;;;106280:25;106297:7;106280:16;:25::i;:::-;106279:26;106199:106;106181:171;;;-1:-1:-1;106339:1:0;;106050:799;-1:-1:-1;;106050:799:0:o;106181:171::-;106380:17;106459:24;;;:15;:24;;;;;;106411:118;;106502:12;106411:29;:118::i;:::-;106364:165;-1:-1:-1;;106546:14:0;106542:55;;-1:-1:-1;106584:1:0;;106050:799;-1:-1:-1;;;106050:799:0:o;106542:55::-;106638:19;;106634:23;;:2;:23;:::i;:::-;106621:37;;:9;:37;:::i;:::-;106609:49;;106671:16;106702:9;;106690;:21;;;;:::i;:::-;106671:40;;106756:7;;106744:8;:19;106740:72;;-1:-1:-1;106791:9:0;106740:72;106832:8;106050:799;-1:-1:-1;;;;106050:799:0:o;39399:335::-;39594:41;16595:10;39627:7;39594:18;:41::i;:::-;39586:99;;;;-1:-1:-1;;;39586:99:0;;;;;;;:::i;:::-;39698:28;39708:4;39714:2;39718:7;39698:9;:28::i;54521:256::-;54618:7;54654:23;54671:5;54654:16;:23::i;:::-;54646:5;:31;54638:87;;;;-1:-1:-1;;;54638:87:0;;13348:2:1;54638:87:0;;;13330:21:1;13387:2;13367:18;;;13360:30;13426:34;13406:18;;;13399:62;-1:-1:-1;;;13477:18:1;;;13470:41;13528:19;;54638:87:0;13146:407:1;54638:87:0;-1:-1:-1;;;;;;54743:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;54521:256::o;103879:1151::-;104003:6;91798:16;91806:7;91798;:16::i;:::-;91790:59;;;;-1:-1:-1;;;91790:59:0;;;;;;;:::i;:::-;91868:17;;;;:8;:17;;;;;;88093:5;-1:-1:-1;91868:33:0;;;:58;;-1:-1:-1;91925:1:0;91905:17;;;:8;:17;;;;;;:21;;91868:58;91860:90;;;;-1:-1:-1;;;91860:90:0;;;;;;;:::i;:::-;104023:7:::1;91672:16;91680:7;91672;:16::i;:::-;91664:49;;;;-1:-1:-1::0;;;91664:49:0::1;;;;;;;:::i;:::-;91500:6:::2;::::0;-1:-1:-1;;;;;91500:6:0::2;:20:::0;;:44:::2;;-1:-1:-1::0;91538:6:0::2;::::0;-1:-1:-1;;;;;91538:6:0::2;91524:10;:20;91500:44;91478:109;;;;-1:-1:-1::0;;;91478:109:0::2;;;;;;;:::i;:::-;104062:3:::3;::::0;:25:::3;::::0;-1:-1:-1;;;104062:25:0;;104076:10:::3;104062:25;::::0;::::3;738:51:1::0;104091:6:0;;-1:-1:-1;;;;;104062:3:0::3;::::0;:13:::3;::::0;711:18:1;;104062:25:0::3;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:35;;104054:69;;;::::0;-1:-1:-1;;;104054:69:0;;15349:2:1;104054:69:0::3;::::0;::::3;15331:21:1::0;15388:2;15368:18;;;15361:30;-1:-1:-1;;;15407:18:1;;;15400:51;15468:18;;104054:69:0::3;15147:345:1::0;104054:69:0::3;104136:20;104159:24;104175:7;104159:15;:24::i;:::-;104136:47;;104234:6;104218:12;:22;;104196:111;;;::::0;-1:-1:-1;;;104196:111:0;;15699:2:1;104196:111:0::3;::::0;::::3;15681:21:1::0;15738:2;15718:18;;;15711:30;15777:34;15757:18;;;15750:62;-1:-1:-1;;;15828:18:1;;;15821:37;15875:19;;104196:111:0::3;15497:403:1::0;104196:111:0::3;104371:7;::::0;104343:23:::3;104360:6:::0;104344:12;104343:23:::3;:::i;:::-;104342:36;;:64;;;;104393:12;104382:6;:24;104342:64;104320:147;;;;-1:-1:-1::0;;;104320:147:0::3;;;;;;;:::i;:::-;104529:10;::::0;104480:19:::3;104575:16:::0;;;:8:::3;:16;::::0;;;;;104480:19;;104502:100:::3;::::0;104554:6;;104502:12:::3;:100::i;:::-;104480:122:::0;-1:-1:-1;104647:21:0::3;104662:6:::0;104647:12;:21:::3;:::i;:::-;104615:29;::::0;;;:20:::3;:29;::::0;;;;;;;:53;;;;104708:15:::3;:24:::0;;;;:38:::3;::::0;104735:11;;104708:38:::3;:::i;:::-;104681:24;::::0;;;:15:::3;:24;::::0;;;;;:65;;;;104783:23;;;;;:37:::3;::::0;104809:11;;104783:37:::3;:::i;:::-;104757:23;::::0;;;:15:::3;:23;::::0;;;;;;;:63;;;;104849:13;:22:::3;::::0;104865:6;;104849:22:::3;:::i;:::-;104833:13;:38:::0;104899:3:::3;::::0;:55:::3;::::0;-1:-1:-1;;;;;104899:3:0::3;104920:10;104940:4;104947:6:::0;104899:20:::3;:55::i;:::-;104980:42;::::0;;16509:25:1;;;16565:2;16550:18;;16543:34;;;16593:18;;;16586:34;;;104980:42:0::3;::::0;16497:2:1;16482:18;104980:42:0::3;;;;;;;104043:987;;91961:1:::1;103879:1151:::0;;;;:::o;123737:258::-;116974:13;:11;:13::i;:::-;123858:28:::1;:58:::0;;;123932:55:::1;::::0;2918:25:1;;;123932:55:0::1;::::0;2906:2:1;2891:18;123932:55:0::1;2772:177:1::0;126154:277:0;116974:13;:11;:13::i;:::-;118906:3:::1;126256:11;:22;;126228:92;;;::::0;-1:-1:-1;;;126228:92:0;;16833:2:1;126228:92:0::1;::::0;::::1;16815:21:1::0;16872:2;16852:18;;;16845:30;16911:34;16891:18;;;16884:62;-1:-1:-1;;;16962:18:1;;;16955:35;17007:19;;126228:92:0::1;16631:401:1::0;126228:92:0::1;126331:10;:24:::0;;;126394:29:::1;::::0;2918:25:1;;;126394:29:0::1;::::0;2906:2:1;2891:18;126394:29:0::1;2772:177:1::0;126645:303:0;116974:13;:11;:13::i;:::-;126721:18:::1;126729:9;126721:7;:18::i;:::-;126713:64;;;::::0;-1:-1:-1;;;126713:64:0;;17239:2:1;126713:64:0::1;::::0;::::1;17221:21:1::0;17278:2;17258:18;;;17251:30;17317:34;17297:18;;;17290:62;-1:-1:-1;;;17368:18:1;;;17361:31;17409:19;;126713:64:0::1;17037:397:1::0;126713:64:0::1;126800:19;::::0;;;:8:::1;:19;::::0;;;;;:24;126792:63:::1;;;::::0;-1:-1:-1;;;126792:63:0;;17641:2:1;126792:63:0::1;::::0;::::1;17623:21:1::0;17680:2;17660:18;;;17653:30;17719:28;17699:18;;;17692:56;17765:18;;126792:63:0::1;17439:350:1::0;126792:63:0::1;126866:19;::::0;;;:8:::1;:19;::::0;;;;;;88093:5:::1;126866:34:::0;;126916:24;::::1;::::0;::::1;::::0;126875:9;2918:25:1;;2906:2;2891:18;;2772:177;39805:185:0;39943:39;39960:4;39966:2;39970:7;39943:39;;;;;;;;;;;;:16;:39::i;128874:250::-;120705:3;;-1:-1:-1;;;;;120705:3:0;120712:10;120705:17;120697:57;;;;-1:-1:-1;;;120697:57:0;;17996:2:1;120697:57:0;;;17978:21:1;18035:2;18015:18;;;18008:30;18074:29;18054:18;;;18047:57;18121:18;;120697:57:0;17794:351:1;120697:57:0;128978:3:::1;::::0;:28:::1;::::0;-1:-1:-1;;;128978:28:0;;129000:4:::1;128978:28;::::0;::::1;738:51:1::0;-1:-1:-1;;;;;128978:3:0;;::::1;::::0;:13:::1;::::0;711:18:1;;128978:28:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;128964:11;:42;128956:79;;;::::0;-1:-1:-1;;;128956:79:0;;18352:2:1;128956:79:0::1;::::0;::::1;18334:21:1::0;18391:2;18371:18;;;18364:30;18430:26;18410:18;;;18403:54;18474:18;;128956:79:0::1;18150:348:1::0;128956:79:0::1;129046:3;::::0;129059::::1;::::0;129046:30:::1;::::0;-1:-1:-1;;;129046:30:0;;-1:-1:-1;;;;;129059:3:0;;::::1;129046:30;::::0;::::1;8639:51:1::0;8706:18;;;8699:34;;;129046:3:0;::::1;::::0;:12:::1;::::0;8612:18:1;;129046:30:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;129092:24:0::1;::::0;2918:25:1;;;129092:24:0::1;::::0;2906:2:1;2891:18;129092:24:0::1;2772:177:1::0;92534:104:0;92590:4;92614:16;92622:7;92614;:16::i;55043:233::-;55118:7;55154:30;54941:10;:17;;54853:113;55154:30;55146:5;:38;55138:95;;;;-1:-1:-1;;;55138:95:0;;18705:2:1;55138:95:0;;;18687:21:1;18744:2;18724:18;;;18717:30;18783:34;18763:18;;;18756:62;-1:-1:-1;;;18834:18:1;;;18827:42;18886:19;;55138:95:0;18503:408:1;55138:95:0;55251:10;55262:5;55251:17;;;;;;;;:::i;:::-;;;;;;;;;55244:24;;55043:233;;;:::o;97936:533::-;98060:7;;98107:10;;98103:306;;88093:5;;98212:19;:17;:19::i;:::-;:34;;;;:::i;:::-;:49;;;;:::i;:::-;98182:8;88483:3;98143:12;98152:3;98143:6;:12;:::i;:::-;:36;;;;:::i;:::-;:47;;;;:::i;:::-;98142:120;;;;:::i;:::-;98134:129;;98103:306;;;88093:5;98362:19;:17;:19::i;:::-;:34;;;;:::i;:::-;88483:3;98304:12;98313:3;98304:6;:12;:::i;:::-;:36;;;;:::i;:::-;98303:94;;;;:::i;:::-;98296:101;;98103:306;98433:28;;98426:35;;:4;:35;:::i;:::-;98419:42;97936:533;-1:-1:-1;;;;;97936:533:0:o;107083:896::-;107143:7;107167:24;;;:15;:24;;;;;;:29;;:59;;;107201:25;107218:7;107201:16;:25::i;:::-;107200:26;107167:59;107163:100;;;-1:-1:-1;107250:1:0;;107083:896;-1:-1:-1;107083:896:0:o;107163:100::-;107273:20;107296:18;107306:7;107296:9;:18::i;:::-;107330:17;107395:24;;;:15;:24;;;;;;107273:41;;-1:-1:-1;107330:17:0;107351:106;;107273:41;107351:29;:106::i;:::-;107327:130;;;107470:16;107501:9;;107489;:21;;;;:::i;:::-;107470:40;-1:-1:-1;107543:13:0;107539:54;;-1:-1:-1;107580:1:0;;107083:896;-1:-1:-1;;;;107083:896:0:o;107539:54::-;107649:7;;107625:19;;107621:23;;:2;:23;:::i;:::-;107607:38;;107608:8;107607:38;:::i;:::-;:49;107603:369;;107802:28;;107779:19;:17;:19::i;:::-;88176:4;107751:9;;107737;:24;;;;:::i;:::-;107736:39;;;;:::i;:::-;:63;;;;:::i;:::-;:94;;;;:::i;107603:369::-;107932:28;;107909:19;:17;:19::i;:::-;88176:4;107883:9;;107871:8;:22;;;;:::i;98585:259::-;98657:10;;98624:7;;98691:14;98657:10;98704:1;98691:14;:::i;:::-;98678:10;:27;;;98724:16;-1:-1:-1;98724:16:0;98716:25;;;;;;98752:21;98758:10;98770:2;98752:5;:21::i;:::-;98789:27;;;19222:25:1;;;98805:10:0;19278:2:1;19263:18;;19256:60;98789:27:0;;19195:18:1;98789:27:0;;;;;;;98834:2;98585:259;-1:-1:-1;98585:259:0:o;128502:123::-;116974:13;:11;:13::i;:::-;128570:2:::1;:8:::0;;;128594:23:::1;::::0;2918:25:1;;;128594:23:0::1;::::0;2906:2:1;2891:18;128594:23:0::1;2772:177:1::0;127660:325:0;127724:9;91798:16;91806:7;91798;:16::i;:::-;91790:59;;;;-1:-1:-1;;;91790:59:0;;;;;;;:::i;:::-;91868:17;;;;:8;:17;;;;;;88093:5;-1:-1:-1;91868:33:0;;;:58;;-1:-1:-1;91925:1:0;91905:17;;;:8;:17;;;;;;:21;;91868:58;91860:90;;;;-1:-1:-1;;;91860:90:0;;;;;;;:::i;:::-;116974:13:::1;:11;:13::i;:::-;127764:18:::2;127772:9;127764:7;:18::i;:::-;127756:67;;;::::0;-1:-1:-1;;;127756:67:0;;19529:2:1;127756:67:0::2;::::0;::::2;19511:21:1::0;19568:2;19548:18;;;19541:30;19607:34;19587:18;;;19580:62;-1:-1:-1;;;19658:18:1;;;19651:34;19702:19;;127756:67:0::2;19327:400:1::0;127756:67:0::2;127864:1;127842:19:::0;;;:8:::2;:19;::::0;;;;;127834:67:::2;;;::::0;-1:-1:-1;;;127834:67:0;;19934:2:1;127834:67:0::2;::::0;::::2;19916:21:1::0;19973:2;19953:18;;;19946:30;20012:33;19992:18;;;19985:61;20063:18;;127834:67:0::2;19732:355:1::0;127834:67:0::2;127934:1;127912:19:::0;;;:8:::2;:19;::::0;;;;;:23;;;;127951:26;::::2;::::0;::::2;::::0;127921:9;2918:25:1;;2906:2;2891:18;;2772:177;124146:219:0;116974:13;:11;:13::i;:::-;124300:7:::1;:18:::0;;;124334:23:::1;::::0;2918:25:1;;;124334:23:0::1;::::0;2906:2:1;2891:18;124334:23:0::1;2772:177:1::0;36897:223:0;36969:7;41784:16;;;:7;:16;;;;;;-1:-1:-1;;;;;41784:16:0;;37033:56;;;;-1:-1:-1;;;37033:56:0;;20650:2:1;37033:56:0;;;20632:21:1;20689:2;20669:18;;;20662:30;-1:-1:-1;;;20708:18:1;;;20701:54;20772:18;;37033:56:0;20448:348:1;105584:249:0;63388:21;:19;:21::i;:::-;-1:-1:-1;;;;;105655:14:0;::::1;;::::0;;;:9:::1;:14;::::0;;;;;105647:60:::1;;;::::0;-1:-1:-1;;;105647:60:0;;21003:2:1;105647:60:0::1;::::0;::::1;20985:21:1::0;21042:2;21022:18;;;21015:30;21081;21061:18;;;21054:58;21129:18;;105647:60:0::1;20801:352:1::0;105647:60:0::1;-1:-1:-1::0;;;;;105735:14:0;;::::1;105718;105735::::0;;;:9:::1;:14;::::0;;;;;;105760:18;;;105789:10:::1;::::0;105735:14;;105789:36:::1;::::0;:10:::1;105745:3:::0;105735:14;105789:23:::1;:36::i;:::-;105636:197;63432:20:::0;62826:1;63952:7;:22;63769:213;63432:20;105584:249;:::o;124532:219::-;116974:13;:11;:13::i;:::-;124686:7:::1;:18:::0;;;124720:23:::1;::::0;2918:25:1;;;124720:23:0::1;::::0;2906:2:1;2891:18;124720:23:0::1;2772:177:1::0;97109:429:0;97219:4;97256:31;97302:17;97333:48;97363:11;97376:4;97333:29;:48::i;:::-;97241:140;;-1:-1:-1;97241:140:0;-1:-1:-1;97394:28:0;97425:35;97241:140;;97425:35;:::i;:::-;97502:28;;-1:-1:-1;97478:52:0;;97109:429;-1:-1:-1;;;;;;97109:429:0:o;124952:183::-;116974:13;:11;:13::i;:::-;-1:-1:-1;;;;;125020:18:0;::::1;125012:63;;;::::0;-1:-1:-1;;;125012:63:0;;21716:2:1;125012:63:0::1;::::0;::::1;21698:21:1::0;;;21735:18;;;21728:30;21794:34;21774:18;;;21767:62;21846:18;;125012:63:0::1;21514:356:1::0;125012:63:0::1;125086:3;:10:::0;;-1:-1:-1;;;;;;125086:10:0::1;-1:-1:-1::0;;;;;125086:10:0;::::1;::::0;;::::1;::::0;;;125112:15:::1;::::0;738:51:1;;;125112:15:0::1;::::0;726:2:1;711:18;125112:15:0::1;592:203:1::0;125341:183:0;116974:13;:11;:13::i;:::-;-1:-1:-1;;;;;125411:18:0;::::1;125403:59;;;::::0;-1:-1:-1;;;125403:59:0;;22077:2:1;125403:59:0::1;::::0;::::1;22059:21:1::0;22116:2;22096:18;;;22089:30;22155;22135:18;;;22128:58;22203:18;;125403:59:0::1;21875:352:1::0;125403:59:0::1;125473:3;:10:::0;;-1:-1:-1;;;;;;125473:10:0::1;-1:-1:-1::0;;;;;125473:10:0;::::1;::::0;;::::1;::::0;;;125499:17:::1;::::0;738:51:1;;;125499:17:0::1;::::0;726:2:1;711:18;125499:17:0::1;592:203:1::0;36628:207:0;36700:7;-1:-1:-1;;;;;36728:19:0;;36720:73;;;;-1:-1:-1;;;36720:73:0;;22434:2:1;36720:73:0;;;22416:21:1;22473:2;22453:18;;;22446:30;22512:34;22492:18;;;22485:62;-1:-1:-1;;;22563:18:1;;;22556:39;22612:19;;36720:73:0;22232:405:1;36720:73:0;-1:-1:-1;;;;;;36811:16:0;;;;;:9;:16;;;;;;;36628:207::o;117736:103::-;116974:13;:11;:13::i;:::-;117801:30:::1;117828:1;117801:18;:30::i;100626:775::-:0;100729:7;91297:16;91305:7;91297;:16::i;:::-;91289:49;;;;-1:-1:-1;;;91289:49:0;;;;;;;:::i;:::-;91377:10;91357:16;91365:7;91357;:16::i;:::-;-1:-1:-1;;;;;91357:30:0;;91349:68;;;;-1:-1:-1;;;91349:68:0;;;;;;;:::i;:::-;63388:21:::1;:19;:21::i;:::-;100798:24:::2;::::0;;;:15:::2;:24;::::0;;;;;:34;-1:-1:-1;100798:34:0::2;100776:121;;;::::0;-1:-1:-1;;;100776:121:0;;23198:2:1;100776:121:0::2;::::0;::::2;23180:21:1::0;23237:2;23217:18;;;23210:30;23276:34;23256:18;;;23249:62;-1:-1:-1;;;23327:18:1;;;23320:35;23372:19;;100776:121:0::2;22996:401:1::0;100776:121:0::2;100910:21;100934:24:::0;;;:15:::2;:24;::::0;;;;;:33:::2;::::0;100961:6;;100934:33:::2;:::i;:::-;100910:57;;100978:12;100993:24;101009:7;100993:15;:24::i;:::-;100978:39:::0;-1:-1:-1;101034:9:0;;101030:204:::2;;101086:38;101104:13;101119:4;101086:17;:38::i;:::-;101060:162;;;::::0;-1:-1:-1;;;101060:162:0;;23604:2:1;101060:162:0::2;::::0;::::2;23586:21:1::0;23643:2;23623:18;;;23616:30;23682:34;23662:18;;;23655:62;23753:32;23733:18;;;23726:60;23803:19;;101060:162:0::2;23402:426:1::0;101060:162:0::2;101246:24;::::0;;;:15:::2;:24;::::0;;;;:40;;;101297:10:::2;::::0;:43:::2;::::0;-1:-1:-1;;;;;101297:10:0::2;101321;101333:6:::0;101297:23:::2;:43::i;:::-;101358:35;::::0;;11279:25:1;;;11335:2;11320:18;;11313:34;;;101358:35:0::2;::::0;11252:18:1;101358:35:0::2;;;;;;;100765:636;;63432:20:::1;62826:1:::0;63952:7;:22;63769:213;99022:578;99103:7;91297:16;91305:7;91297;:16::i;:::-;91289:49;;;;-1:-1:-1;;;91289:49:0;;;;;;;:::i;:::-;91377:10;91357:16;91365:7;91357;:16::i;:::-;-1:-1:-1;;;;;91357:30:0;;91349:68;;;;-1:-1:-1;;;91349:68:0;;;;;;;:::i;:::-;63388:21:::1;:19;:21::i;:::-;99158:18:::2;99168:7;99158:9;:18::i;:::-;:23:::0;99150:62:::2;;;::::0;-1:-1:-1;;;99150:62:0;;24035:2:1;99150:62:0::2;::::0;::::2;24017:21:1::0;24074:2;24054:18;;;24047:30;24113:28;24093:18;;;24086:56;24159:18;;99150:62:0::2;23833:350:1::0;99150:62:0::2;99229:24;::::0;;;:15:::2;:24;::::0;;;;;:29;99225:174:::2;;99320:67;99344:16;99352:7;99344;:16::i;:::-;99362:24;::::0;;;:15:::2;:24;::::0;;;;;99320:10:::2;::::0;-1:-1:-1;;;;;99320:10:0::2;::::0;:67;:23:::2;:67::i;:::-;99411:14;99417:7;99411:5;:14::i;:::-;99445:24;::::0;;;:15:::2;:24;::::0;;;;;;;99438:31;;;99487:20:::2;:29:::0;;;;;99480:36;;;99534:12:::2;:21:::0;;;;;99527:28;;;;99571:21;;2918:25:1;;;99571:21:0::2;::::0;2891:18:1;99571:21:0::2;;;;;;;63432:20:::1;62826:1:::0;63952:7;:22;63769:213;63432:20:::1;99022:578:::0;;:::o;125701:277::-;116974:13;:11;:13::i;:::-;118906:3:::1;125803:11;:22;;125775:92;;;::::0;-1:-1:-1;;;125775:92:0;;24390:2:1;125775:92:0::1;::::0;::::1;24372:21:1::0;24429:2;24409:18;;;24402:30;24468:34;24448:18;;;24441:62;-1:-1:-1;;;24519:18:1;;;24512:35;24564:19;;125775:92:0::1;24188:401:1::0;125775:92:0::1;125878:10;:24:::0;;;125941:29:::1;::::0;2918:25:1;;;125941:29:0::1;::::0;2906:2:1;2891:18;125941:29:0::1;2772:177:1::0;113771:2071:0;113852:7;113835;91672:16;91680:7;91672;:16::i;:::-;91664:49;;;;-1:-1:-1;;;91664:49:0;;;;;;;:::i;:::-;113894:13:::1;::::0;-1:-1:-1;;;;;113894:13:0::1;:27:::0;;:58:::1;;-1:-1:-1::0;113939:13:0::1;::::0;-1:-1:-1;;;;;113939:13:0::1;113925:10;:27;113894:58;113872:140;;;::::0;-1:-1:-1;;;113872:140:0;;24796:2:1;113872:140:0::1;::::0;::::1;24778:21:1::0;;;24815:18;;;24808:30;24874:34;24854:18;;;24847:62;24926:18;;113872:140:0::1;24594:356:1::0;113872:140:0::1;114021:20;114044:24;114060:7;114044:15;:24::i;:::-;114021:47:::0;-1:-1:-1;114089:17:0;114081:45:::1;;;::::0;-1:-1:-1;;;114081:45:0;;25157:2:1;114081:45:0::1;::::0;::::1;25139:21:1::0;25196:2;25176:18;;;25169:30;-1:-1:-1;;;25215:18:1;;;25208:45;25270:18;;114081:45:0::1;24955:339:1::0;114081:45:0::1;114154:31;114279:24:::0;;;:15:::1;:24;::::0;;;;;114154:31;;114231:118:::1;::::0;114322:12;114231:29:::1;:118::i;:::-;114139:210:::0;;-1:-1:-1;114139:210:0;-1:-1:-1;114362:28:0::1;114393:37;114139:210:::0;;114393:37:::1;:::i;:::-;114492:9;::::0;114362:68;;-1:-1:-1;114464:23:0::1;114362:68:::0;114485:2:::1;114464:23;:::i;:::-;114463:38;;114441:135;;;::::0;-1:-1:-1;;;114441:135:0;;25501:2:1;114441:135:0::1;::::0;::::1;25483:21:1::0;25540:2;25520:18;;;25513:30;25579:34;25559:18;;;25552:62;-1:-1:-1;;;25630:18:1;;;25623:44;25684:19;;114441:135:0::1;25299:410:1::0;114441:135:0::1;114589:23;114798:19;;114794:2;:23;;;;:::i;:::-;114762:28;;:56;;;;:::i;:::-;114696:123;::::0;:23;:123:::1;:::i;:::-;114633:19;::::0;114629:23:::1;::::0;:2:::1;:23;:::i;:::-;114616:37;::::0;:9;:37:::1;:::i;:::-;114615:205;;;;:::i;:::-;114909:3;::::0;:25:::1;::::0;-1:-1:-1;;;114909:25:0;;114923:10:::1;114909:25;::::0;::::1;738:51:1::0;114589:231:0;;-1:-1:-1;114589:231:0;;-1:-1:-1;;;;;114909:3:0;;::::1;::::0;:13:::1;::::0;711:18:1;;114909:25:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;;114901:94;;;::::0;-1:-1:-1;;;114901:94:0;;25916:2:1;114901:94:0::1;::::0;::::1;25898:21:1::0;25955:2;25935:18;;;25928:30;25994:34;25974:18;;;25967:62;-1:-1:-1;;;26045:18:1;;;26038:35;26090:19;;114901:94:0::1;25714:401:1::0;114901:94:0::1;115021:3;::::0;:64:::1;::::0;-1:-1:-1;;;;;115021:3:0::1;115042:10;115062:4;115069:15:::0;115021:20:::1;:64::i;:::-;115129:15;115112:13;;:33;;;;:::i;:::-;115096:13;:49:::0;115192:16:::1;115211:13;:11;:13::i;:::-;115350:24;::::0;;;:15:::1;:24;::::0;;;;;;115322:25;;;;;:52;115192:32;-1:-1:-1;115418:30:0::1;115433:15:::0;115418:12;:30:::1;:::i;:::-;115385;::::0;;;:20:::1;:30;::::0;;;;;;;:63;;;;115459:12:::1;:22:::0;;;;;115484:15:::1;115459:40:::0;;115562:24;;;:15:::1;:24:::0;;;;;115555:31;;;115604:29;;;;;;115597:36;;;;115738:68;;26351:25:1;;;26392:18;;;26385:34;;;115778:10:0::1;26435:18:1::0;;;26428:60;26519:2;26504:18;;26497:34;;;115738:68:0;;::::1;::::0;;;;26338:3:1;115738:68:0;;::::1;115824:8:::0;-1:-1:-1;;;;;;91724:1:0::1;113771:2071:::0;;;;:::o;95283:454::-;95341:7;95362:11;95375:12;95391:25;95408:7;95391:16;:25::i;:::-;95361:55;;;;95449:3;95439:7;;:13;;;;:::i;:::-;95429:7;:23;95481:13;;:19;;95497:3;;95481:19;:::i;:::-;95465:13;:35;95516:2;;:6;95513:77;;95539:21;;;;:12;:21;;;;;95563:15;95539:39;;95513:77;95669:29;;;;:20;:29;;;;;;:36;;;-1:-1:-1;95701:4:0;;95283:454;-1:-1:-1;95283:454:0:o;92186:110::-;92260:3;;:28;;-1:-1:-1;;;92260:28:0;;92282:4;92260:28;;;738:51:1;92233:7:0;;-1:-1:-1;;;;;92260:3:0;;:13;;711:18:1;;92260:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;92253:35;;92186:110;:::o;110962:2349::-;111058:6;91798:16;91806:7;91798;:16::i;:::-;91790:59;;;;-1:-1:-1;;;91790:59:0;;;;;;;:::i;:::-;91868:17;;;;:8;:17;;;;;;88093:5;-1:-1:-1;91868:33:0;;;:58;;-1:-1:-1;91925:1:0;91905:17;;;:8;:17;;;;;;:21;;91868:58;91860:90;;;;-1:-1:-1;;;91860:90:0;;;;;;;:::i;:::-;111087:7:::1;91672:16;91680:7;91672;:16::i;:::-;91664:49;;;;-1:-1:-1::0;;;91664:49:0::1;;;;;;;:::i;:::-;111134:13:::2;::::0;-1:-1:-1;;;;;111134:13:0::2;:27:::0;;:58:::2;;-1:-1:-1::0;111179:13:0::2;::::0;-1:-1:-1;;;;;111179:13:0::2;111165:10;:27;111134:58;111112:142;;;::::0;-1:-1:-1;;;111112:142:0;;26744:2:1;111112:142:0::2;::::0;::::2;26726:21:1::0;26783:2;26763:18;;;26756:30;26822:34;26802:18;;;26795:62;-1:-1:-1;;;26873:18:1;;;26866:32;26915:19;;111112:142:0::2;26542:398:1::0;111112:142:0::2;111267:20;111290:24;111306:7;111290:15;:24::i;:::-;111340:31;111465:24:::0;;;:15:::2;:24;::::0;;;;;111267:47;;-1:-1:-1;111340:31:0;;;111417:118:::2;::::0;111267:47;111417:29:::2;:118::i;:::-;111325:210;;;;111554:12;111570:1;111554:17;;111546:45;;;::::0;-1:-1:-1;;;111546:45:0;;25157:2:1;111546:45:0::2;::::0;::::2;25139:21:1::0;25196:2;25176:18;;;25169:30;-1:-1:-1;;;25215:18:1;;;25208:45;25270:18;;111546:45:0::2;24955:339:1::0;111546:45:0::2;111604:28;111635:37;111662:9:::0;111635:23;:37:::2;:::i;:::-;111604:68;;111730:28;;111707:20;:51;111685:149;;;::::0;-1:-1:-1;;;111685:149:0;;27147:2:1;111685:149:0::2;::::0;::::2;27129:21:1::0;27186:2;27166:18;;;27159:30;27225:34;27205:18;;;27198:62;-1:-1:-1;;;27276:18:1;;;27269:46;27332:19;;111685:149:0::2;26945:412:1::0;111685:149:0::2;111883:9;::::0;111855:25:::2;:20:::0;111878:2:::2;111855:25;:::i;:::-;:37;111847:80;;;::::0;-1:-1:-1;;;111847:80:0;;27564:2:1;111847:80:0::2;::::0;::::2;27546:21:1::0;27603:2;27583:18;;;27576:30;27642:31;27622:18;;;27615:59;27691:18;;111847:80:0::2;27362:353:1::0;111847:80:0::2;111969:19;::::0;111965:23:::2;::::0;:2:::2;:23;:::i;:::-;111952:37;::::0;:9;:37:::2;:::i;:::-;111940:49;;112002:16;112034:9;;112021;:23;;;;:::i;:::-;112002:42;;112089:7;;112077:8;:19;112073:72;;-1:-1:-1::0;112124:9:0;112073:72:::2;112179:3;::::0;:25:::2;::::0;-1:-1:-1;;;112179:25:0;;112193:10:::2;112179:25;::::0;::::2;738:51:1::0;112208:8:0;;-1:-1:-1;;;;;112179:3:0::2;::::0;:13:::2;::::0;711:18:1;;112179:25:0::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:37;;112157:136;;;::::0;-1:-1:-1;;;112157:136:0;;27922:2:1;112157:136:0::2;::::0;::::2;27904:21:1::0;27961:2;27941:18;;;27934:30;28000:34;27980:18;;;27973:62;-1:-1:-1;;;28051:18:1;;;28044:47;28108:19;;112157:136:0::2;27720:413:1::0;112157:136:0::2;112339:8;112322:13;;:26;;;;:::i;:::-;112306:13;:42:::0;112361:20:::2;112384:21;112397:7:::0;112384:12:::2;:21::i;:::-;112361:44:::0;-1:-1:-1;112450:25:0::2;112466:8:::0;112450:12;:25:::2;:::i;:::-;112418:29;::::0;;;:20:::2;:29;::::0;;;;;;;:57;;;;112557:10:::2;::::0;112579:16;;;:8:::2;:16:::0;;;;;;;112418:29;;112544:52:::2;::::0;112569:8;;112544:12:::2;:52::i;:::-;112634:24;::::0;;;:15:::2;:24;::::0;;;;;112522:74;;-1:-1:-1;112634:40:0::2;::::0;112522:74;;112634:40:::2;:::i;:::-;112607:24;::::0;;;:15:::2;:24;::::0;;;;;:67;;;;112711:23;;;;;:39:::2;::::0;112738:11;;112711:39:::2;:::i;:::-;112685:23;::::0;;;:15:::2;:23;::::0;;;;;:65;;;;112858:24;;;;;:41:::2;::::0;112886:12;;112858:41:::2;:::i;:::-;112831:24;::::0;;;:15:::2;:24;::::0;;;;;;;:68;;;;112993:10:::2;112983:21:::0;;:9:::2;:21:::0;;;;:38:::2;::::0;113008:12;;112983:38:::2;:::i;:::-;112969:10;112959:21;::::0;;;:9:::2;:21;::::0;;;;:62;;;;113049:3:::2;::::0;:57:::2;::::0;-1:-1:-1;;;;;113049:3:0;;::::2;::::0;113090:4:::2;113097:8:::0;113049:20:::2;:57::i;:::-;113124:179;113153:7;113175:16;113183:7;113175;:16::i;:::-;113124:179;::::0;;28425:25:1;;;-1:-1:-1;;;;;28524:15:1;;;28519:2;28504:18;;28497:43;113206:10:0::2;28556:18:1::0;;;28549:43;28623:2;28608:18;;28601:34;;;28666:3;28651:19;;28644:35;;;28477:3;28695:19;;28688:35;;;28412:3;28397:19;113124:179:0::2;;;;;;;111101:2210;;;;;;;91961:1:::1;110962:2349:::0;;;:::o;37356:104::-;37412:13;37445:7;37438:14;;;;;:::i;101762:1365::-;101893:6;91798:16;91806:7;91798;:16::i;:::-;91790:59;;;;-1:-1:-1;;;91790:59:0;;;;;;;:::i;:::-;91868:17;;;;:8;:17;;;;;;88093:5;-1:-1:-1;91868:33:0;;;:58;;-1:-1:-1;91925:1:0;91905:17;;;:8;:17;;;;;;:21;;91868:58;91860:90;;;;-1:-1:-1;;;91860:90:0;;;;;;;:::i;:::-;101922:7:::1;91297:16;91305:7;91297;:16::i;:::-;91289:49;;;;-1:-1:-1::0;;;91289:49:0::1;;;;;;;:::i;:::-;91377:10;91357:16;91365:7:::0;91357::::1;:16::i;:::-;-1:-1:-1::0;;;;;91357:30:0::1;;91349:68;;;;-1:-1:-1::0;;;91349:68:0::1;;;;;;;:::i;:::-;63388:21:::2;:19;:21::i;:::-;101985:1:::3;101976:6;:10;101968:50;;;::::0;-1:-1:-1;;;101968:50:0;;28936:2:1;101968:50:0::3;::::0;::::3;28918:21:1::0;28975:2;28955:18;;;28948:30;29014:29;28994:18;;;28987:57;29061:18;;101968:50:0::3;28734:351:1::0;101968:50:0::3;102061:16;:14;:16::i;:::-;102051:6;:26;;102029:123;;;::::0;-1:-1:-1;;;102029:123:0;;29292:2:1;102029:123:0::3;::::0;::::3;29274:21:1::0;29331:2;29311:18;;;29304:30;29370:34;29350:18;;;29343:62;-1:-1:-1;;;29421:18:1;;;29414:45;29476:19;;102029:123:0::3;29090:411:1::0;102029:123:0::3;102165:15;102210:6;102183:24;102199:7;102183:15;:24::i;:::-;:33;;;;:::i;:::-;102165:51;;102246:7;;102237;:16;;102229:63;;;::::0;-1:-1:-1;;;102229:63:0;;29708:2:1;102229:63:0::3;::::0;::::3;29690:21:1::0;29747:2;29727:18;;;29720:30;29786:34;29766:18;;;29759:62;-1:-1:-1;;;29837:18:1;;;29830:32;29879:19;;102229:63:0::3;29506:398:1::0;102229:63:0::3;102323:18;102333:7;102323:9;:18::i;:::-;102313:7;:28;102305:37;;;::::0;::::3;;102397:24;::::0;;;:15:::3;:24;::::0;;;;;102379:52:::3;::::0;102423:7;102379:17:::3;:52::i;:::-;102357:160;;;::::0;-1:-1:-1;;;102357:160:0;;30111:2:1;102357:160:0::3;::::0;::::3;30093:21:1::0;30150:2;30130:18;;;30123:30;30189:34;30169:18;;;30162:62;30260:28;30240:18;;;30233:56;30306:19;;102357:160:0::3;29909:422:1::0;102357:160:0::3;102587:7;;102576:6;102554:18;102564:7;102554:9;:18::i;:::-;102553:29;;;;:::i;:::-;102552:42;;102530:125;;;;-1:-1:-1::0;;;102530:125:0::3;;;;;;;:::i;:::-;102668:29;::::0;;;:20:::3;:29;::::0;;;;;;;:39;;;102755:10:::3;::::0;102776:16;;;:8:::3;:16:::0;;;;;;102742:51:::3;::::0;102755:10;102700:7;;102742:12:::3;:51::i;:::-;102833:24;::::0;;;:15:::3;:24;::::0;;;;;102720:73;;-1:-1:-1;102833:40:0::3;::::0;102720:73;;102833:40:::3;:::i;:::-;102806:24;::::0;;;:15:::3;:24;::::0;;;;;:67;;;;102910:23;;;;;:39:::3;::::0;102937:11;;102910:39:::3;:::i;:::-;102884:23;::::0;;;:15:::3;:23;::::0;;;;:65;102986:3:::3;::::0;:36:::3;::::0;-1:-1:-1;;;;;102986:3:0::3;103003:10;103015:6:::0;102986:16:::3;:36::i;:::-;103066:6;103049:13;;:24;;;;:::i;:::-;103033:13;:40:::0;;;103091:28:::3;::::0;;11279:25:1;;;11320:18;;;11313:34;;;103091:28:0::3;::::0;11252:18:1;103091:28:0::3;;;;;;;101955:1172;;63432:20:::2;62826:1:::0;63952:7;:22;63769:213;63432:20:::2;91961:1:::1;101762:1365:::0;;;;:::o;93701:114::-;93778:14;;:29;;;-1:-1:-1;;;93778:29:0;;;;93751:7;;-1:-1:-1;;;;;93778:14:0;;:27;;:29;;;;;;;;;;;;;;:14;:29;;;;;;;;;;;;;;122741:231;116974:13;:11;:13::i;:::-;-1:-1:-1;;;;;122820:19:0;::::1;122812:69;;;::::0;-1:-1:-1;;;122812:69:0;;30538:2:1;122812:69:0::1;::::0;::::1;30520:21:1::0;30577:2;30557:18;;;30550:30;30616:34;30596:18;;;30589:62;-1:-1:-1;;;30667:18:1;;;30660:34;30711:19;;122812:69:0::1;30336:400:1::0;122812:69:0::1;122892:13;:21:::0;;-1:-1:-1;;;;;;122892:21:0::1;-1:-1:-1::0;;;;;122892:21:0;::::1;::::0;;::::1;::::0;;;122929:35:::1;::::0;738:51:1;;;122929:35:0::1;::::0;726:2:1;711:18;122929:35:0::1;592:203:1::0;38942:155:0;39037:52;16595:10;39070:8;39080;39037:18;:52::i;120927:149::-;116974:13;:11;:13::i;:::-;121006:20;;::::1;::::0;:10:::1;::::0;:20:::1;::::0;::::1;::::0;::::1;:::i;:::-;;121042:26;121060:7;121042:26;;;;;;:::i;92788:252::-:0;92924:10;;:35;;-1:-1:-1;;;92924:35:0;;92953:4;92924:35;;;738:51:1;92842:7:0;;-1:-1:-1;;;;;92924:10:0;;:20;;711:18:1;;92924:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;92893:28;;92871:19;:17;:19::i;:::-;:50;;;;:::i;:::-;:88;;;;:::i;109861:702::-;109945:4;109927:7;91672:16;91680:7;91672;:16::i;:::-;91664:49;;;;-1:-1:-1;;;91664:49:0;;;;;;;:::i;:::-;109964:20:::1;109987:18;109997:7;109987:9;:18::i;:::-;110022:24;::::0;;;:15:::1;:24;::::0;;;;;109964:41;;-1:-1:-1;110022:29:0;;:50:::1;;-1:-1:-1::0;110055:17:0;;110022:50:::1;110018:95;;;110096:5;110089:12;;;;;110018:95;110140:31;110265:24:::0;;;:15:::1;:24;::::0;;;;;110140:31;;110217:118:::1;::::0;110308:12;110217:29:::1;:118::i;:::-;110125:210:::0;;-1:-1:-1;110125:210:0;-1:-1:-1;110348:28:0::1;110379:37;110125:210:::0;;110379:37:::1;:::i;:::-;110462:9;::::0;110348:68;;-1:-1:-1;110434:23:0::1;110348:68:::0;110455:2:::1;110434:23;:::i;:::-;110433:38;110429:127;;110495:4;110488:11;;;;;;;;110429:127;110539:5;110532:12;;;;;;;;108909:753:::0;109030:4;109003:7;91672:16;91680:7;91672;:16::i;:::-;91664:49;;;;-1:-1:-1;;;91664:49:0;;;;;;;:::i;:::-;109052:20:::1;109075:18;109085:7;109075:9;:18::i;:::-;109110:24;::::0;;;:15:::1;:24;::::0;;;;;109052:41;;-1:-1:-1;109110:29:0;;:50:::1;;-1:-1:-1::0;109143:17:0;;109110:50:::1;109106:95;;;109184:5;109177:12;;;;;109106:95;109228:31;109353:24:::0;;;:15:::1;:24;::::0;;;;;109228:31;;109305:118:::1;::::0;109396:12;109305:29:::1;:118::i;:::-;109213:210:::0;;-1:-1:-1;109213:210:0;-1:-1:-1;109436:28:0::1;109467:37;109213:210:::0;;109467:37:::1;:::i;:::-;109436:68;;109542:28;;109519:20;:51;109515:140;;;109594:4;109587:11;;;;;;;;40061:322:::0;40235:41;16595:10;40268:7;40235:18;:41::i;:::-;40227:99;;;;-1:-1:-1;;;40227:99:0;;;;;;;:::i;:::-;40337:38;40351:4;40357:2;40361:7;40370:4;40337:13;:38::i;:::-;40061:322;;;;:::o;129403:88::-;116974:13;:11;:13::i;:::-;129469:6:::1;:14:::0;;-1:-1:-1;;;;;;129469:14:0::1;-1:-1:-1::0;;;;;129469:14:0;;;::::1;::::0;;;::::1;::::0;;129403:88::o;60883:147::-;60948:13;60982:16;60990:7;60982;:16::i;:::-;60974:25;;;;;;61019:3;61012:10;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60883:147;;;:::o;127217:311::-;127299:9;91798:16;91806:7;91798;:16::i;:::-;91790:59;;;;-1:-1:-1;;;91790:59:0;;;;;;;:::i;:::-;91868:17;;;;:8;:17;;;;;;88093:5;-1:-1:-1;91868:33:0;;;:58;;-1:-1:-1;91925:1:0;91905:17;;;:8;:17;;;;;;:21;;91868:58;91860:90;;;;-1:-1:-1;;;91860:90:0;;;;;;;:::i;:::-;127325:9:::1;91297:16;91305:7;91297;:16::i;:::-;91289:49;;;;-1:-1:-1::0;;;91289:49:0::1;;;;;;;:::i;:::-;91377:10;91357:16;91365:7:::0;91357::::1;:16::i;:::-;-1:-1:-1::0;;;;;91357:30:0::1;;91349:68;;;;-1:-1:-1::0;;;91349:68:0::1;;;;;;;:::i;:::-;127366:1:::2;127355:8;:12;:40;;;;;88093:5;127371:8;:24;;127355:40;127347:80;;;::::0;-1:-1:-1;;;127347:80:0;;30943:2:1;127347:80:0::2;::::0;::::2;30925:21:1::0;30982:2;30962:18;;;30955:30;31021:29;31001:18;;;30994:57;31068:18;;127347:80:0::2;30741:351:1::0;127347:80:0::2;127438:19;::::0;;;:8:::2;:19;::::0;;;;;;;;:30;;;127484:36;;11279:25:1;;;11320:18;;;11313:34;;;127484:36:0::2;::::0;11252:18:1;127484:36:0::2;;;;;;;;91961:1:::1;127217:311:::0;;;:::o;105146:266::-;63388:21;:19;:21::i;:::-;105216:10:::1;105206:21;::::0;;;:9:::1;:21;::::0;;;;;105198:67:::1;;;::::0;-1:-1:-1;;;105198:67:0;;21003:2:1;105198:67:0::1;::::0;::::1;20985:21:1::0;21042:2;21022:18;;;21015:30;21081;21061:18;;;21054:58;21129:18;;105198:67:0::1;20801:352:1::0;105198:67:0::1;105303:10;105276:14;105293:21:::0;;;:9:::1;:21;::::0;;;;;;105325:25;;;105361:10:::1;::::0;105293:21;;105361:43:::1;::::0;-1:-1:-1;;;;;105361:10:0::1;::::0;105293:21;105361:23:::1;:43::i;:::-;105187:225;63432:20:::0;62826:1;63952:7;:22;63769:213;103135:405;103266:6;91798:16;91806:7;91798;:16::i;:::-;91790:59;;;;-1:-1:-1;;;91790:59:0;;;;;;;:::i;:::-;91868:17;;;;:8;:17;;;;;;88093:5;-1:-1:-1;91868:33:0;;;:58;;-1:-1:-1;91925:1:0;91905:17;;;:8;:17;;;;;;:21;;91868:58;91860:90;;;;-1:-1:-1;;;91860:90:0;;;;;;;:::i;:::-;103286:7:::1;91672:16;91680:7;91672;:16::i;:::-;91664:49;;;;-1:-1:-1::0;;;91664:49:0::1;;;;;;;:::i;:::-;91500:6:::2;::::0;-1:-1:-1;;;;;91500:6:0::2;:20:::0;;:44:::2;;-1:-1:-1::0;91538:6:0::2;::::0;-1:-1:-1;;;;;91538:6:0::2;91524:10;:20;91500:44;91478:109;;;;-1:-1:-1::0;;;91478:109:0::2;;;;;;;:::i;:::-;103351:15:::3;103339:8;:27;;103317:111;;;::::0;-1:-1:-1;;;103317:111:0;;31299:2:1;103317:111:0::3;::::0;::::3;31281:21:1::0;31338:2;31318:18;;;31311:30;31377:34;31357:18;;;31350:62;-1:-1:-1;;;31428:18:1;;;31421:32;31470:19;;103317:111:0::3;31097:398:1::0;103317:111:0::3;103441:15;103459:24;103475:7;103459:15;:24::i;:::-;103441:42;;103494:38;103507:7;103516;103525:6;103494:12;:38::i;:::-;103306:234;91961:1:::1;103135:405:::0;;;;:::o;94926:151::-;94983:7;95006:12;95022:25;95039:7;95022:16;:25::i;108129:585::-;108259:7;108232;91672:16;91680:7;91672;:16::i;:::-;91664:49;;;;-1:-1:-1;;;91664:49:0;;;;;;;:::i;:::-;108284:20:::1;108307:18;108317:7;108307:9;:18::i;:::-;108342:24;::::0;;;:15:::1;:24;::::0;;;;;108284:41;;-1:-1:-1;108342:29:0;;:50:::1;;-1:-1:-1::0;108375:17:0;;108342:50:::1;108338:91;;;108416:1;108409:8;;;;;108338:91;108454:31;108579:24:::0;;;:15:::1;:24;::::0;;;;;108454:31;;108531:118:::1;::::0;108622:12;108531:29:::1;:118::i;:::-;108439:210:::0;;-1:-1:-1;108439:210:0;-1:-1:-1;108669:37:0::1;108439:210:::0;;108669:37:::1;:::i;:::-;108662:44:::0;108129:585;-1:-1:-1;;;;;;108129:585:0:o;129268:127::-;116974:13;:11;:13::i;:::-;129341:10:::1;:3;129347:4:::0;;129341:10:::1;:::i;:::-;;129367:20;129383:3;129367:20;;;;;;:::i;60313:17::-:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;121698:206::-;116974:13;:11;:13::i;:::-;121778:15;121770:50:::1;;;::::0;-1:-1:-1;;;121770:50:0;;33019:2:1;121770:50:0::1;::::0;::::1;33001:21:1::0;33058:2;33038:18;;;33031:30;-1:-1:-1;;;33077:18:1;;;33070:52;33139:18;;121770:50:0::1;32817:346:1::0;121770:50:0::1;121831:9;:22:::0;;;121869:27:::1;::::0;2918:25:1;;;121869:27:0::1;::::0;2906:2:1;2891:18;121869:27:0::1;2772:177:1::0;99878:454:0;99977:7;91672:16;91680:7;91672;:16::i;:::-;91664:49;;;;-1:-1:-1;;;91664:49:0;;;;;;;:::i;:::-;91500:6:::1;::::0;-1:-1:-1;;;;;91500:6:0::1;:20:::0;;:44:::1;;-1:-1:-1::0;91538:6:0::1;::::0;-1:-1:-1;;;;;91538:6:0::1;91524:10;:20;91500:44;91478:109;;;;-1:-1:-1::0;;;91478:109:0::1;;;;;;;:::i;:::-;100022:21:::2;100046:24:::0;;;:15:::2;:24;::::0;;;;;:35:::2;::::0;100074:6;;100046:35:::2;:::i;:::-;100119:24;::::0;;;:15:::2;:24;::::0;;;;;100022:59;;-1:-1:-1;100102:41:0;::::2;;100094:50;;;::::0;::::2;;100157:24;::::0;;;:15:::2;:24;::::0;;;;:40;;;100210:10:::2;::::0;:62:::2;::::0;-1:-1:-1;;;;;100210:10:0::2;100238;100258:4;100265:6:::0;100210:27:::2;:62::i;:::-;100290:34;::::0;;11279:25:1;;;11335:2;11320:18;;11313:34;;;100290::0::2;::::0;11252:18:1;100290:34:0::2;11105:248:1::0;117994:201:0;116974:13;:11;:13::i;:::-;-1:-1:-1;;;;;118083:22:0;::::1;118075:73;;;::::0;-1:-1:-1;;;118075:73:0;;33370:2:1;118075:73:0::1;::::0;::::1;33352:21:1::0;33409:2;33389:18;;;33382:30;33448:34;33428:18;;;33421:62;-1:-1:-1;;;33499:18:1;;;33492:36;33545:19;;118075:73:0::1;33168:402:1::0;118075:73:0::1;118159:28;118178:8;118159:18;:28::i;121273:233::-:0;116974:13;:11;:13::i;:::-;121367:4:::1;121353:10;:18;;121345:77;;;::::0;-1:-1:-1;;;121345:77:0;;33777:2:1;121345:77:0::1;::::0;::::1;33759:21:1::0;33816:2;33796:18;;;33789:30;33855:34;33835:18;;;33828:62;-1:-1:-1;;;33906:18:1;;;33899:44;33960:19;;121345:77:0::1;33575:410:1::0;121345:77:0::1;121433:9;:22:::0;;;121471:27:::1;::::0;2918:25:1;;;121471:27:0::1;::::0;2906:2:1;2891:18;121471:27:0::1;2772:177:1::0;55350:915:0;55527:61;55554:4;55560:2;55564:12;55578:9;55527:26;:61::i;:::-;55617:1;55605:9;:13;55601:222;;;55748:63;;-1:-1:-1;;;55748:63:0;;34192:2:1;55748:63:0;;;34174:21:1;34231:2;34211:18;;;34204:30;34270:34;34250:18;;;34243:62;-1:-1:-1;;;34321:18:1;;;34314:51;34382:19;;55748:63:0;33990:417:1;55601:222:0;55853:12;-1:-1:-1;;;;;55882:18:0;;55878:187;;55917:40;55949:7;57092:10;:17;;57065:24;;;;:15;:24;;;;;:44;;;57120:24;;;;;;;;;;;;56988:164;55917:40;55878:187;;;55987:2;-1:-1:-1;;;;;55979:10:0;:4;-1:-1:-1;;;;;55979:10:0;;55975:90;;56006:47;56039:4;56045:7;56006:32;:47::i;:::-;-1:-1:-1;;;;;56079:16:0;;56075:183;;56112:45;56149:7;56112:36;:45::i;:::-;56075:183;;;56185:4;-1:-1:-1;;;;;56179:10:0;:2;-1:-1:-1;;;;;56179:10:0;;56175:83;;56206:40;56234:2;56238:7;56206:27;:40::i;50802:410::-;50992:1;50980:9;:13;50976:229;;;-1:-1:-1;;;;;51014:18:0;;;51010:87;;-1:-1:-1;;;;;51053:15:0;;;;;;:9;:15;;;;;:28;;51072:9;;51053:15;:28;;51072:9;;51053:28;:::i;:::-;;;;-1:-1:-1;;51010:87:0;-1:-1:-1;;;;;51115:16:0;;;51111:83;;-1:-1:-1;;;;;51152:13:0;;;;;;:9;:13;;;;;:26;;51169:9;;51152:13;:26;;51169:9;;51152:26;:::i;:::-;;;;-1:-1:-1;;50802:410:0;;;;:::o;63468:293::-;62870:1;63602:7;;:19;;63594:63;;;;-1:-1:-1;;;63594:63:0;;34614:2:1;63594:63:0;;;34596:21:1;34653:2;34633:18;;;34626:30;34692:33;34672:18;;;34665:61;34743:18;;63594:63:0;34412:355:1;63594:63:0;62870:1;63735:7;:18;63468:293::o;54213:224::-;54315:4;-1:-1:-1;;;;;;54339:50:0;;-1:-1:-1;;;54339:50:0;;:90;;;54393:36;54417:11;54393:23;:36::i;117253:132::-;117161:6;;-1:-1:-1;;;;;117161:6:0;16595:10;117317:23;117309:68;;;;-1:-1:-1;;;117309:68:0;;34974:2:1;117309:68:0;;;34956:21:1;;;34993:18;;;34986:30;35052:34;35032:18;;;35025:62;35104:18;;117309:68:0;34772:356:1;48518:135:0;48600:16;48608:7;48600;:16::i;:::-;48592:53;;;;-1:-1:-1;;;48592:53:0;;20650:2:1;48592:53:0;;;20632:21:1;20689:2;20669:18;;;20662:30;-1:-1:-1;;;20708:18:1;;;20701:54;20772:18;;48592:53:0;20448:348:1;47797:174:0;47872:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;47872:29:0;-1:-1:-1;;;;;47872:29:0;;;;;;;;:24;;47926:23;47872:24;47926:14;:23::i;:::-;-1:-1:-1;;;;;47917:46:0;;;;;;;;;;;47797:174;;:::o;96100:713::-;96224:7;96233;96266:19;:17;:19::i;:::-;96258:33;;;;;;96350:23;96438:28;;96403:19;:17;:19::i;:::-;96376:46;;:11;:46;:::i;:::-;:90;;;;:::i;:::-;96350:116;;96506:11;96487:15;:30;;96479:39;;;;;;96531:17;96551:29;88483:3;96551:5;:29;:::i;:::-;96531:49;;96614:5;96601:9;:18;;96593:27;;;;;;96633:31;96667:21;:15;96685:3;96667:21;:::i;:::-;96633:55;;96733:15;96707:23;:41;96699:50;;;;;;96770:23;96795:9;;-1:-1:-1;96100:713:0;-1:-1:-1;;;;96100:713:0:o;42416:264::-;42509:4;42526:13;42542:23;42557:7;42542:14;:23::i;:::-;42526:39;;42595:5;-1:-1:-1;;;;;42584:16:0;:7;-1:-1:-1;;;;;42584:16:0;;:52;;;-1:-1:-1;;;;;;39289:25:0;;;39265:4;39289:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;42604:32;42584:87;;;;42664:7;-1:-1:-1;;;;;42640:31:0;:20;42652:7;42640:11;:20::i;:::-;-1:-1:-1;;;;;42640:31:0;;42576:96;42416:264;-1:-1:-1;;;;42416:264:0:o;46415:1263::-;46574:4;-1:-1:-1;;;;;46547:31:0;:23;46562:7;46547:14;:23::i;:::-;-1:-1:-1;;;;;46547:31:0;;46539:81;;;;-1:-1:-1;;;46539:81:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;46639:16:0;;46631:65;;;;-1:-1:-1;;;46631:65:0;;35741:2:1;46631:65:0;;;35723:21:1;35780:2;35760:18;;;35753:30;35819:34;35799:18;;;35792:62;-1:-1:-1;;;35870:18:1;;;35863:34;35914:19;;46631:65:0;35539:400:1;46631:65:0;46709:42;46730:4;46736:2;46740:7;46749:1;46709:20;:42::i;:::-;46881:4;-1:-1:-1;;;;;46854:31:0;:23;46869:7;46854:14;:23::i;:::-;-1:-1:-1;;;;;46854:31:0;;46846:81;;;;-1:-1:-1;;;46846:81:0;;;;;;;:::i;:::-;46999:24;;;;:15;:24;;;;;;;;46992:31;;-1:-1:-1;;;;;;46992:31:0;;;;;;-1:-1:-1;;;;;47475:15:0;;;;;;:9;:15;;;;;:20;;-1:-1:-1;;47475:20:0;;;47510:13;;;;;;;;;:18;;46992:31;47510:18;;;47550:16;;;:7;:16;;;;;;:21;;;;;;;;;;47589:27;;47015:7;;47589:27;;;38287:346;38217:416;;:::o;42121:128::-;42186:4;41784:16;;;:7;:16;;;;;;-1:-1:-1;;;;;41784:16:0;42210:31;;;42121:128::o;84257:248::-;84428:68;;-1:-1:-1;;;;;36202:15:1;;;84428:68:0;;;36184:34:1;36254:15;;36234:18;;;36227:43;36286:18;;;36279:34;;;84401:96:0;;84421:5;;-1:-1:-1;;;84451:27:0;36119:18:1;;84428:68:0;;;;-1:-1:-1;;84428:68:0;;;;;;;;;;;;;;-1:-1:-1;;;;;84428:68:0;-1:-1:-1;;;;;;84428:68:0;;;;;;;;;;84401:19;:96::i;44014:942::-;-1:-1:-1;;;;;44094:16:0;;44086:61;;;;-1:-1:-1;;;44086:61:0;;36526:2:1;44086:61:0;;;36508:21:1;;;36545:18;;;36538:30;36604:34;36584:18;;;36577:62;36656:18;;44086:61:0;36324:356:1;44086:61:0;44167:16;44175:7;44167;:16::i;:::-;44166:17;44158:58;;;;-1:-1:-1;;;44158:58:0;;36887:2:1;44158:58:0;;;36869:21:1;36926:2;36906:18;;;36899:30;36965;36945:18;;;36938:58;37013:18;;44158:58:0;36685:352:1;44158:58:0;44229:48;44258:1;44262:2;44266:7;44275:1;44229:20;:48::i;:::-;44376:16;44384:7;44376;:16::i;:::-;44375:17;44367:58;;;;-1:-1:-1;;;44367:58:0;;36887:2:1;44367:58:0;;;36869:21:1;36926:2;36906:18;;;36899:30;36965;36945:18;;;36938:58;37013:18;;44367:58:0;36685:352:1;44367:58:0;-1:-1:-1;;;;;44774:13:0;;;;;;:9;:13;;;;;;;;:18;;44791:1;44774:18;;;44816:16;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;44816:21:0;;;;;44855:33;44824:7;;44774:13;;44855:33;;44774:13;;44855:33;99022:578;;:::o;84038:211::-;84182:58;;-1:-1:-1;;;;;8657:32:1;;84182:58:0;;;8639:51:1;8706:18;;;8699:34;;;84155:86:0;;84175:5;;-1:-1:-1;;;84205:23:0;8612:18:1;;84182:58:0;8465:274:1;118355:191:0;118448:6;;;-1:-1:-1;;;;;118465:17:0;;;-1:-1:-1;;;;;;118465:17:0;;;;;;;118498:40;;118448:6;;;118465:17;118448:6;;118498:40;;118429:16;;118498:40;118418:128;118355:191;:::o;45295:783::-;45355:13;45371:23;45386:7;45371:14;:23::i;:::-;45355:39;;45407:51;45428:5;45443:1;45447:7;45456:1;45407:20;:51::i;:::-;45571:23;45586:7;45571:14;:23::i;:::-;45642:24;;;;:15;:24;;;;;;;;45635:31;;-1:-1:-1;;;;;;45635:31:0;;;;;;-1:-1:-1;;;;;45887:16:0;;;;;:9;:16;;;;;:21;;-1:-1:-1;;45887:21:0;;;45937:16;;;:7;:16;;;;;;45930:23;;;;;;;45971:36;45563:31;;-1:-1:-1;45658:7:0;;45971:36;;45642:24;;45971:36;99022:578;;:::o;94117:577::-;94210:7;94307:29;;;:20;:29;;;;;;;;;94377:12;:21;;;;;;94210:7;;94266:15;;94210:7;;94377:26;;;;:36;;;94412:1;94407:2;;:6;94377:36;94373:285;;;94430:17;94464:21;;;:12;:21;;;;;;94450:35;;:11;:35;:::i;:::-;94430:55;;94502:18;88093:5;88133:8;94539:9;94531:4;94526:2;;:9;;;;:::i;:::-;94525:23;;;;:::i;:::-;94524:36;;;;:::i;:::-;94523:53;;;;:::i;:::-;94502:74;-1:-1:-1;94502:74:0;;-1:-1:-1;94629:17:0;94642:4;94502:74;94629:17;:::i;:::-;94622:24;;94415:243;;94373:285;94676:3;94681:4;;-1:-1:-1;94117:577:0;-1:-1:-1;;;94117:577:0:o;48114:315::-;48269:8;-1:-1:-1;;;;;48260:17:0;:5;-1:-1:-1;;;;;48260:17:0;;;48252:55;;;;-1:-1:-1;;;48252:55:0;;37244:2:1;48252:55:0;;;37226:21:1;37283:2;37263:18;;;37256:30;37322:27;37302:18;;;37295:55;37367:18;;48252:55:0;37042:349:1;48252:55:0;-1:-1:-1;;;;;48318:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;48318:46:0;;;;;;;;;;48380:41;;540::1;;;48380::0;;513:18:1;48380:41:0;;;;;;;48114:315;;;:::o;41264:313::-;41420:28;41430:4;41436:2;41440:7;41420:9;:28::i;:::-;41467:47;41490:4;41496:2;41500:7;41509:4;41467:22;:47::i;:::-;41459:110;;;;-1:-1:-1;;;41459:110:0;;;;;;;:::i;57779:988::-;58045:22;58095:1;58070:22;58087:4;58070:16;:22::i;:::-;:26;;;;:::i;:::-;58107:18;58128:26;;;:17;:26;;;;;;58045:51;;-1:-1:-1;58261:28:0;;;58257:328;;-1:-1:-1;;;;;58328:18:0;;58306:19;58328:18;;;:12;:18;;;;;;;;:34;;;;;;;;;58379:30;;;;;;:44;;;58496:30;;:17;:30;;;;;:43;;;58257:328;-1:-1:-1;58681:26:0;;;;:17;:26;;;;;;;;58674:33;;;-1:-1:-1;;;;;58725:18:0;;;;;:12;:18;;;;;:34;;;;;;;58718:41;57779:988::o;59062:1079::-;59340:10;:17;59315:22;;59340:21;;59360:1;;59340:21;:::i;:::-;59372:18;59393:24;;;:15;:24;;;;;;59766:10;:26;;59315:46;;-1:-1:-1;59393:24:0;;59315:46;;59766:26;;;;;;:::i;:::-;;;;;;;;;59744:48;;59830:11;59805:10;59816;59805:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;59910:28;;;:15;:28;;;;;;;:41;;;60082:24;;;;;60075:31;60117:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;59133:1008;;;59062:1079;:::o;56566:221::-;56651:14;56668:20;56685:2;56668:16;:20::i;:::-;-1:-1:-1;;;;;56699:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;56744:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;56566:221:0:o;36259:305::-;36361:4;-1:-1:-1;;;;;;36398:40:0;;-1:-1:-1;;;36398:40:0;;:105;;-1:-1:-1;;;;;;;36455:48:0;;-1:-1:-1;;;36455:48:0;36398:105;:158;;;-1:-1:-1;;;;;;;;;;34793:40:0;;;36520:36;34684:157;60339:211;60486:56;60513:4;60519:2;60523:7;60532:9;60486:26;:56::i;87105:716::-;87529:23;87555:69;87583:4;87555:69;;;;;;;;;;;;;;;;;87563:5;-1:-1:-1;;;;;87555:27:0;;;:69;;;;;:::i;:::-;87639:17;;87529:95;;-1:-1:-1;87639:21:0;87635:179;;87736:10;87725:30;;;;;;;;;;;;:::i;:::-;87717:85;;;;-1:-1:-1;;;87717:85:0;;38149:2:1;87717:85:0;;;38131:21:1;38188:2;38168:18;;;38161:30;38227:34;38207:18;;;38200:62;-1:-1:-1;;;38278:18:1;;;38271:40;38328:19;;87717:85:0;37947:406:1;49217:853:0;49371:4;-1:-1:-1;;;;;49392:13:0;;1899:19;:23;49388:675;;49428:71;;-1:-1:-1;;;49428:71:0;;-1:-1:-1;;;;;49428:36:0;;;;;:71;;16595:10;;49479:4;;49485:7;;49494:4;;49428:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;49428:71:0;;;;;;;;-1:-1:-1;;49428:71:0;;;;;;;;;;;;:::i;:::-;;;49424:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;49669:13:0;;49665:328;;49712:60;;-1:-1:-1;;;49712:60:0;;;;;;;:::i;49665:328::-;49943:6;49937:13;49928:6;49924:2;49920:15;49913:38;49424:584;-1:-1:-1;;;;;;49550:51:0;-1:-1:-1;;;49550:51:0;;-1:-1:-1;49543:58:0;;49388:675;-1:-1:-1;50047:4:0;49217:853;;;;;;:::o;4361:229::-;4498:12;4530:52;4552:6;4560:4;4566:1;4569:12;4498;5769;5783:23;5810:6;-1:-1:-1;;;;;5810:11:0;5829:5;5836:4;5810:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5768:73;;;;5859:69;5886:6;5894:7;5903:10;5915:12;5859:26;:69::i;:::-;5852:76;5481:455;-1:-1:-1;;;;;;;5481:455:0:o;8054:644::-;8239:12;8268:7;8264:427;;;8296:17;;8292:290;;-1:-1:-1;;;;;1899:19:0;;;8506:60;;;;-1:-1:-1;;;8506:60:0;;39994:2:1;8506:60:0;;;39976:21:1;40033:2;40013:18;;;40006:30;40072:31;40052:18;;;40045:59;40121:18;;8506:60:0;39792:353:1;8506:60:0;-1:-1:-1;8603:10:0;8596:17;;8264:427;8646:33;8654:10;8666:12;9401:17;;:21;9397:388;;9633:10;9627:17;9690:15;9677:10;9673:2;9669:19;9662:44;9397:388;9760:12;9753:20;;-1:-1:-1;;;9753:20:0;;;;;;;;:::i;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:131:1;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;:::-;384:5;150:245;-1:-1:-1;;;150:245:1:o;955:258::-;1027:1;1037:113;1051:6;1048:1;1045:13;1037:113;;;1127:11;;;1121:18;1108:11;;;1101:39;1073:2;1066:10;1037:113;;;1168:6;1165:1;1162:13;1159:48;;;-1:-1:-1;;1203:1:1;1185:16;;1178:27;955:258::o;1218:::-;1260:3;1298:5;1292:12;1325:6;1320:3;1313:19;1341:63;1397:6;1390:4;1385:3;1381:14;1374:4;1367:5;1363:16;1341:63;:::i;:::-;1458:2;1437:15;-1:-1:-1;;1433:29:1;1424:39;;;;1465:4;1420:50;;1218:258;-1:-1:-1;;1218:258:1:o;1481:220::-;1630:2;1619:9;1612:21;1593:4;1650:45;1691:2;1680:9;1676:18;1668:6;1650:45;:::i;1706:173::-;1774:20;;-1:-1:-1;;;;;1823:31:1;;1813:42;;1803:70;;1869:1;1866;1859:12;1803:70;1706:173;;;:::o;1884:186::-;1943:6;1996:2;1984:9;1975:7;1971:23;1967:32;1964:52;;;2012:1;2009;2002:12;1964:52;2035:29;2054:9;2035:29;:::i;2075:180::-;2134:6;2187:2;2175:9;2166:7;2162:23;2158:32;2155:52;;;2203:1;2200;2193:12;2155:52;-1:-1:-1;2226:23:1;;2075:180;-1:-1:-1;2075:180:1:o;2260:254::-;2328:6;2336;2389:2;2377:9;2368:7;2364:23;2360:32;2357:52;;;2405:1;2402;2395:12;2357:52;2428:29;2447:9;2428:29;:::i;:::-;2418:39;2504:2;2489:18;;;;2476:32;;-1:-1:-1;;;2260:254:1:o;2519:248::-;2587:6;2595;2648:2;2636:9;2627:7;2623:23;2619:32;2616:52;;;2664:1;2661;2654:12;2616:52;-1:-1:-1;;2687:23:1;;;2757:2;2742:18;;;2729:32;;-1:-1:-1;2519:248:1:o;2954:328::-;3031:6;3039;3047;3100:2;3088:9;3079:7;3075:23;3071:32;3068:52;;;3116:1;3113;3106:12;3068:52;3139:29;3158:9;3139:29;:::i;:::-;3129:39;;3187:38;3221:2;3210:9;3206:18;3187:38;:::i;:::-;3177:48;;3272:2;3261:9;3257:18;3244:32;3234:42;;2954:328;;;;;:::o;3287:316::-;3364:6;3372;3380;3433:2;3421:9;3412:7;3408:23;3404:32;3401:52;;;3449:1;3446;3439:12;3401:52;-1:-1:-1;;3472:23:1;;;3542:2;3527:18;;3514:32;;-1:-1:-1;3593:2:1;3578:18;;;3565:32;;3287:316;-1:-1:-1;3287:316:1:o;4246:118::-;4332:5;4325:13;4318:21;4311:5;4308:32;4298:60;;4354:1;4351;4344:12;4369:315;4434:6;4442;4495:2;4483:9;4474:7;4470:23;4466:32;4463:52;;;4511:1;4508;4501:12;4463:52;4534:29;4553:9;4534:29;:::i;:::-;4524:39;;4613:2;4602:9;4598:18;4585:32;4626:28;4648:5;4626:28;:::i;:::-;4673:5;4663:15;;;4369:315;;;;;:::o;4689:127::-;4750:10;4745:3;4741:20;4738:1;4731:31;4781:4;4778:1;4771:15;4805:4;4802:1;4795:15;4821:632;4886:5;4916:18;4957:2;4949:6;4946:14;4943:40;;;4963:18;;:::i;:::-;5038:2;5032:9;5006:2;5092:15;;-1:-1:-1;;5088:24:1;;;5114:2;5084:33;5080:42;5068:55;;;5138:18;;;5158:22;;;5135:46;5132:72;;;5184:18;;:::i;:::-;5224:10;5220:2;5213:22;5253:6;5244:15;;5283:6;5275;5268:22;5323:3;5314:6;5309:3;5305:16;5302:25;5299:45;;;5340:1;5337;5330:12;5299:45;5390:6;5385:3;5378:4;5370:6;5366:17;5353:44;5445:1;5438:4;5429:6;5421;5417:19;5413:30;5406:41;;;;4821:632;;;;;:::o;5458:451::-;5527:6;5580:2;5568:9;5559:7;5555:23;5551:32;5548:52;;;5596:1;5593;5586:12;5548:52;5636:9;5623:23;5669:18;5661:6;5658:30;5655:50;;;5701:1;5698;5691:12;5655:50;5724:22;;5777:4;5769:13;;5765:27;-1:-1:-1;5755:55:1;;5806:1;5803;5796:12;5755:55;5829:74;5895:7;5890:2;5877:16;5872:2;5868;5864:11;5829:74;:::i;5914:667::-;6009:6;6017;6025;6033;6086:3;6074:9;6065:7;6061:23;6057:33;6054:53;;;6103:1;6100;6093:12;6054:53;6126:29;6145:9;6126:29;:::i;:::-;6116:39;;6174:38;6208:2;6197:9;6193:18;6174:38;:::i;:::-;6164:48;;6259:2;6248:9;6244:18;6231:32;6221:42;;6314:2;6303:9;6299:18;6286:32;6341:18;6333:6;6330:30;6327:50;;;6373:1;6370;6363:12;6327:50;6396:22;;6449:4;6441:13;;6437:27;-1:-1:-1;6427:55:1;;6478:1;6475;6468:12;6427:55;6501:74;6567:7;6562:2;6549:16;6544:2;6540;6536:11;6501:74;:::i;:::-;6491:84;;;5914:667;;;;;;;:::o;6586:592::-;6657:6;6665;6718:2;6706:9;6697:7;6693:23;6689:32;6686:52;;;6734:1;6731;6724:12;6686:52;6774:9;6761:23;6803:18;6844:2;6836:6;6833:14;6830:34;;;6860:1;6857;6850:12;6830:34;6898:6;6887:9;6883:22;6873:32;;6943:7;6936:4;6932:2;6928:13;6924:27;6914:55;;6965:1;6962;6955:12;6914:55;7005:2;6992:16;7031:2;7023:6;7020:14;7017:34;;;7047:1;7044;7037:12;7017:34;7092:7;7087:2;7078:6;7074:2;7070:15;7066:24;7063:37;7060:57;;;7113:1;7110;7103:12;7060:57;7144:2;7136:11;;;;;7166:6;;-1:-1:-1;6586:592:1;;-1:-1:-1;;;;6586:592:1:o;7183:260::-;7251:6;7259;7312:2;7300:9;7291:7;7287:23;7283:32;7280:52;;;7328:1;7325;7318:12;7280:52;7351:29;7370:9;7351:29;:::i;:::-;7341:39;;7399:38;7433:2;7422:9;7418:18;7399:38;:::i;:::-;7389:48;;7183:260;;;;;:::o;7808:127::-;7869:10;7864:3;7860:20;7857:1;7850:31;7900:4;7897:1;7890:15;7924:4;7921:1;7914:15;7940:168;7980:7;8046:1;8042;8038:6;8034:14;8031:1;8028:21;8023:1;8016:9;8009:17;8005:45;8002:71;;;8053:18;;:::i;:::-;-1:-1:-1;8093:9:1;;7940:168::o;8113:217::-;8153:1;8179;8169:132;;8223:10;8218:3;8214:20;8211:1;8204:31;8258:4;8255:1;8248:15;8286:4;8283:1;8276:15;8169:132;-1:-1:-1;8315:9:1;;8113:217::o;8335:125::-;8375:4;8403:1;8400;8397:8;8394:34;;;8408:18;;:::i;:::-;-1:-1:-1;8445:9:1;;8335:125::o;8744:245::-;8811:6;8864:2;8852:9;8843:7;8839:23;8835:32;8832:52;;;8880:1;8877;8870:12;8832:52;8912:9;8906:16;8931:28;8953:5;8931:28;:::i;8994:380::-;9073:1;9069:12;;;;9116;;;9137:61;;9191:4;9183:6;9179:17;9169:27;;9137:61;9244:2;9236:6;9233:14;9213:18;9210:38;9207:161;;;9290:10;9285:3;9281:20;9278:1;9271:31;9325:4;9322:1;9315:15;9353:4;9350:1;9343:15;10617:128;10657:3;10688:1;10684:6;10681:1;10678:13;10675:39;;;10694:18;;:::i;:::-;-1:-1:-1;10730:9:1;;10617:128::o;11358:422::-;11447:1;11490:5;11447:1;11504:270;11525:7;11515:8;11512:21;11504:270;;;11584:4;11580:1;11576:6;11572:17;11566:4;11563:27;11560:53;;;11593:18;;:::i;:::-;11643:7;11633:8;11629:22;11626:55;;;11663:16;;;;11626:55;11742:22;;;;11702:15;;;;11504:270;;;11508:3;11358:422;;;;;:::o;11785:806::-;11834:5;11864:8;11854:80;;-1:-1:-1;11905:1:1;11919:5;;11854:80;11953:4;11943:76;;-1:-1:-1;11990:1:1;12004:5;;11943:76;12035:4;12053:1;12048:59;;;;12121:1;12116:130;;;;12028:218;;12048:59;12078:1;12069:10;;12092:5;;;12116:130;12153:3;12143:8;12140:17;12137:43;;;12160:18;;:::i;:::-;-1:-1:-1;;12216:1:1;12202:16;;12231:5;;12028:218;;12330:2;12320:8;12317:16;12311:3;12305:4;12302:13;12298:36;12292:2;12282:8;12279:16;12274:2;12268:4;12265:12;12261:35;12258:77;12255:159;;;-1:-1:-1;12367:19:1;;;12399:5;;12255:159;12446:34;12471:8;12465:4;12446:34;:::i;:::-;12516:6;12512:1;12508:6;12504:19;12495:7;12492:32;12489:58;;;12527:18;;:::i;:::-;12565:20;;11785:806;-1:-1:-1;;;11785:806:1:o;12596:131::-;12656:5;12685:36;12712:8;12706:4;12685:36;:::i;12732:409::-;12934:2;12916:21;;;12973:2;12953:18;;;12946:30;13012:34;13007:2;12992:18;;12985:62;-1:-1:-1;;;13078:2:1;13063:18;;13056:43;13131:3;13116:19;;12732:409::o;13558:354::-;13760:2;13742:21;;;13799:2;13779:18;;;13772:30;13838:32;13833:2;13818:18;;13811:60;13903:2;13888:18;;13558:354::o;13917:343::-;14119:2;14101:21;;;14158:2;14138:18;;;14131:30;-1:-1:-1;;;14192:2:1;14177:18;;14170:49;14251:2;14236:18;;13917:343::o;14265:344::-;14467:2;14449:21;;;14506:2;14486:18;;;14479:30;-1:-1:-1;;;14540:2:1;14525:18;;14518:50;14600:2;14585:18;;14265:344::o;14614:339::-;14816:2;14798:21;;;14855:2;14835:18;;;14828:30;-1:-1:-1;;;14889:2:1;14874:18;;14867:45;14944:2;14929:18;;14614:339::o;14958:184::-;15028:6;15081:2;15069:9;15060:7;15056:23;15052:32;15049:52;;;15097:1;15094;15087:12;15049:52;-1:-1:-1;15120:16:1;;14958:184;-1:-1:-1;14958:184:1:o;15905:397::-;16107:2;16089:21;;;16146:2;16126:18;;;16119:30;16185:34;16180:2;16165:18;;16158:62;-1:-1:-1;;;16251:2:1;16236:18;;16229:31;16292:3;16277:19;;15905:397::o;18916:127::-;18977:10;18972:3;18968:20;18965:1;18958:31;19008:4;19005:1;18998:15;19032:4;19029:1;19022:15;22642:349;22844:2;22826:21;;;22883:2;22863:18;;;22856:30;22922:27;22917:2;22902:18;;22895:55;22982:2;22967:18;;22642:349::o;31626:1186::-;31735:4;31764:2;31793;31782:9;31775:21;31816:1;31849:6;31843:13;31879:3;31901:1;31929:9;31925:2;31921:18;31911:28;;31989:2;31978:9;31974:18;32011;32001:61;;32055:4;32047:6;32043:17;32033:27;;32001:61;32108:2;32100:6;32097:14;32077:18;32074:38;32071:165;;;-1:-1:-1;;;32135:33:1;;32191:4;32188:1;32181:15;32221:4;32142:3;32209:17;32071:165;32292:18;;;887:19;;;939:4;930:14;32335:18;32362:100;;;;32476:1;32471:315;;;;32328:458;;32362:100;-1:-1:-1;;32395:24:1;;32383:37;;32440:12;;;;-1:-1:-1;32362:100:1;;32471:315;31573:1;31566:14;;;31610:4;31597:18;;32566:1;32580:165;32594:6;32591:1;32588:13;32580:165;;;32672:14;;32659:11;;;32652:35;32715:16;;;;32609:10;;32580:165;;;32765:11;;;-1:-1:-1;;32328:458:1;-1:-1:-1;32803:3:1;;31626:1186;-1:-1:-1;;;;;;;;;31626:1186:1:o;35133:401::-;35335:2;35317:21;;;35374:2;35354:18;;;35347:30;35413:34;35408:2;35393:18;;35386:62;-1:-1:-1;;;35479:2:1;35464:18;;35457:35;35524:3;35509:19;;35133:401::o;37396:414::-;37598:2;37580:21;;;37637:2;37617:18;;;37610:30;37676:34;37671:2;37656:18;;37649:62;-1:-1:-1;;;37742:2:1;37727:18;;37720:48;37800:3;37785:19;;37396:414::o;37815:127::-;37876:10;37871:3;37867:20;37864:1;37857:31;37907:4;37904:1;37897:15;37931:4;37928:1;37921:15;38358:489;-1:-1:-1;;;;;38627:15:1;;;38609:34;;38679:15;;38674:2;38659:18;;38652:43;38726:2;38711:18;;38704:34;;;38774:3;38769:2;38754:18;;38747:31;;;38552:4;;38795:46;;38821:19;;38813:6;38795:46;:::i;38852:249::-;38921:6;38974:2;38962:9;38953:7;38949:23;38945:32;38942:52;;;38990:1;38987;38980:12;38942:52;39022:9;39016:16;39041:30;39065:5;39041:30;:::i;39513:274::-;39642:3;39680:6;39674:13;39696:53;39742:6;39737:3;39730:4;39722:6;39718:17;39696:53;:::i;:::-;39765:16;;;;;39513:274;-1:-1:-1;;39513:274:1:o
Swarm Source
ipfs://9cd2fad0217ea9c2d9e87e38e582ad46b394b173ccecfa37a23400b5e0359e6b
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.