Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block | From | To | Value | ||
---|---|---|---|---|---|---|
16789662 | 482 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Contract Name:
CoverNFTDescriptor
Compiler Version
v0.8.18+commit.87f61d96
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; import "@openzeppelin/contracts-v4/utils/Base64.sol"; import "@openzeppelin/contracts-v4/utils/Strings.sol"; import "../../interfaces/ICover.sol"; import "../../interfaces/ICoverNFT.sol"; import "../../interfaces/ICoverNFTDescriptor.sol"; import "../../interfaces/IERC20Detailed.sol"; import "../../interfaces/INXMMaster.sol"; import "../../interfaces/IPool.sol"; import "../../libraries/DateTime.sol"; import "../../libraries/FloatingPoint.sol"; import "./CoverNFT.sol"; contract CoverNFTDescriptor is ICoverNFTDescriptor { using Strings for uint; using DateTime for uint; INXMMaster immutable public master; struct CoverDescription { string productName; string assetSymbol; string expiryDate; uint coverAmount; uint id; uint decimals; } constructor(INXMMaster _master) { master = _master; } function tokenURI(uint tokenId) public view returns (string memory) { (string memory descriptionString, CoverDescription memory descriptionData) = generateDescription(tokenId); string memory image = Base64.encode(bytes(generateSVGImage(descriptionData))); return string( abi.encodePacked( "data:application/json;base64,", Base64.encode( bytes( abi.encodePacked( '{"name":"', ICoverNFT(msg.sender).name(), '",', '"description":"', descriptionString, '",', '"image": "', 'data:image/svg+xml;base64,', image, '"}' ) ) ) ) ); } function generateDescription(uint tokenId) public view returns (string memory descriptionString, CoverDescription memory descriptionData) { ICover cover = ICover(master.getLatestAddress("CO")); if (cover.coverDataCount() < tokenId) { return ("This NFT does not exist", CoverDescription("", "", "", 0, 0, 0)); } // Get cover data CoverData memory coverData = cover.coverData(tokenId); string memory productName = cover.productNames(coverData.productId); CoverSegment memory lastSegment = cover.coverSegmentWithRemainingAmount(tokenId, cover.coverSegmentsCount(tokenId) - 1); // Check if cover has already expired string memory expiryMessage; if ((lastSegment.start + lastSegment.period) <= block.timestamp) { expiryMessage = "This cover NFT has already expired"; } string memory expiry; { // Format expiry date (uint year, uint month, uint day) = uint(lastSegment.start + lastSegment.period).timestampToDate(); expiry = string( abi.encodePacked( month.getMonthString(), " ", addZeroPrefix(day), " ", year.toString() ) ); } // Encode final description descriptionString = string( abi.encodePacked( "This NFT represents a cover purchase made for: ", productName, " \\nAmount Covered: ", FloatingPoint.toFloat(uint(lastSegment.amount), getAssetDecimals(coverData.coverAsset))," ", getAssetSymbol(coverData.coverAsset), " \\nExpiry Date: ", expiry, " \\n", expiryMessage ) ); descriptionData = CoverDescription( productName, getAssetSymbol(coverData.coverAsset), expiry, lastSegment.amount, tokenId, getAssetDecimals(coverData.coverAsset) ); return (descriptionString, descriptionData); } // If value is single digit, add a zero prefix function addZeroPrefix(uint256 value) public pure returns (string memory) { if (value < 10) { return string(abi.encodePacked("0", value.toString())); } return value.toString(); } function getAssetDecimals(uint assetId) public view returns (uint decimals) { if (assetId == 0) { return 18; } IPool pool = IPool(master.getLatestAddress("P1")); Asset memory asset = pool.getAsset(assetId); decimals = IERC20Detailed(asset.assetAddress).decimals(); } function getAssetSymbol(uint assetId) public view returns (string memory assetSymbol) { if (assetId == 0) { return "ETH"; } IPool pool = IPool(master.getLatestAddress("P1")); Asset memory asset = pool.getAsset(assetId); assetSymbol = IERC20Detailed(asset.assetAddress).symbol(); } function generateSVGImage(CoverDescription memory descriptionData) public pure returns (bytes memory image) { string memory svgData = string(abi.encodePacked( '<tspan>', descriptionData.productName, '</tspan></text> <text class="cls-9" x="93%" y="40%" text-anchor="end">', '<tspan>', FloatingPoint.toFloat(descriptionData.coverAmount, descriptionData.decimals), " ", descriptionData.assetSymbol, '</tspan></text>', '<text class="cls-9" x="93%" y="45%" text-anchor="end"><tspan>', descriptionData.expiryDate,'</tspan></text>', '<text class="cls-9" x="93%" y="50%" text-anchor="end"><tspan>', descriptionData.id.toString(),'</tspan></text> </g></svg>' )); return abi.encodePacked( string( abi.encodePacked( // Image data '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 290 500"> <defs> <style> .cls-1 { fill: none; } .cls-3 { clip-path: url(#cp1); } .cls-4 { opacity: .04; } .cls-5 { fill: #055037; } .cls-6, .cls-7, .cls-8, .cls-9 { fill: #fff; } .cls-7 { font-size: 18px; } .cls-7, .cls-8, .cls-9 { font-family: ArialMT, Arial, sans-serif; } .cls-9 { clip-path: url(#cp2); } .cls-8, .cls-9 { font-size: 13px; } </style> <clipPath id="cp1"> <rect class="cls-1" width="290" height="500" rx="32.74" ry="32.74"/> </clipPath> <clipPath id="cp2"> <rect class="cls-1" x="-382.18" y="-90" width="968.85" height="971"/> </clipPath> </defs> <g> <rect class="cls-5" y="0" width="290" height="500" rx="32.74" ry="32.74"/> <g> <path class="cls-6" d="m137.65,344.29c5.97-5.76,6.14-15.26.38-21.23s-15.26-6.14-21.23-.38-6.14,15.26-.38,21.23c5.76,5.97,15.26,6.14,21.23.38Z"/> <path class="cls-6" d="m55.85,382.84c5.97-5.76,6.14-15.26.38-21.23s-15.26-6.14-21.23-.38c-5.97,5.76-6.14,15.26-.38,21.23,5.76,5.97,15.26,6.14,21.23.38Z"/> <path class="cls-6" d="m95.2,443.55c-5.78-5.95-15.28-6.09-21.23-.31-5.92,5.75-6.09,15.2-.38,21.16h0c5.7,6.02,15.2,6.28,21.23.58,6.02-5.7,6.28-15.2.58-21.23-.06-.07-.13-.14-.2-.2Z"/> <path class="cls-6" d="m176.38,404.39c-5.76-5.97-15.26-6.14-21.23-.38-5.97,5.76-6.14,15.26-.38,21.23,5.76,5.97,15.26,6.14,21.23.38,5.97-5.76,6.14-15.26.38-21.23Z"/> <path class="cls-6" d="m170.2,369.41c2.85-2.87,4.35-6.82,4.13-10.86v-.11c-.68-12.34-15.65-18.07-24.39-9.33l-14.15,14.4c-4.53,4.53-15,5.22-20.37-.16l-33.84-34.24c-2.69-2.78-6.4-4.35-10.27-4.35-12.74,0-19.11,15.4-10.1,24.41l14.27,13.77c5.19,5.65,4.62,15.6,0,20.22l-34.28,34.35c-2.64,2.64-4.14,6.21-4.19,9.94v.32c-.15,12.82,15.34,19.34,24.4,10.28l14.24-14.31c4.96-4.96,15.27-5.01,20.46.18l33.7,33.9c2.79,2.79,6.6,4.3,10.53,4.18h.05c12.53-.37,18.55-15.54,9.69-24.4l-13.61-13.75c-5.05-5.05-5.43-14.79-.03-20.19l33.77-34.25Zm-53.42,35.38c-6.27,6.05-16.26,5.87-22.32-.4-6.05-6.27-5.87-16.26.4-22.32,6.27-6.05,16.26-5.87,22.32.4,6.05,6.27,5.87,16.26-.4,22.32Z"/> </g> <rect class="cls-1" width="290" height="500" rx="32.74" ry="32.74"/> <g class="cls-4"> <g class="cls-3"> <g class="cls-9"> <path class="cls-6" d="m166.21,199.57L0,31.41v468.59h279.42c2.06-8.38,5.24-16.47,9.58-23.93V207.76c-32.29,22.54-91.17,23.44-122.79-8.18Zm8.78,267.25c-40.45,39.03-104.88,37.88-143.92-2.57-39.03-40.45-37.88-104.88,2.57-143.92,40.45-39.03,104.88-37.88,143.92,2.57,39.03,40.45,37.88,104.88-2.57,143.92Z"/> <path class="cls-6" d="m290,0h-144.24c-1.92,26.48,6.99,53.64,26.88,74.26,31.32,32.46,79.85,38.32,117.36,17.07V0Z"/> </g> </g> </g> <g> <polygon class="cls-6" points="221.16 46.69 217.76 55.77 216.64 55.77 213.24 46.69 213.24 55.77 210.67 55.77 210.67 43.28 214.27 43.28 217.2 50.64 220.13 43.28 223.75 43.28 223.75 55.77 221.16 55.77 221.16 46.69"/> <rect class="cls-6" x="265.25" y="42.99" width="2.43" height="12.78"/> <g> <path class="cls-6" d="m204.34,47.11c1.18-1.13,1.22-3,.08-4.18-1.15-1.18-3-1.22-4.18-.07-1.16,1.12-1.19,3-.09,4.16,1.13,1.18,3.01,1.22,4.19.1"/> <path class="cls-6" d="m184.16,54.75c1.13,1.18,3,1.22,4.18.08,1.18-1.15,1.22-3,.07-4.18-1.12-1.16-3-1.19-4.16-.09-1.18,1.13-1.22,3.01-.1,4.19"/> <path class="cls-6" d="m176.56,34.43c-1.18,1.13-1.22,3-.08,4.18,1.15,1.18,3,1.22,4.18.07,1.16-1.12,1.19-3,.09-4.16-1.13-1.18-3.01-1.22-4.19-.1"/> <path class="cls-6" d="m196.86,26.91c-1.13-1.18-3-1.22-4.18-.08-1.18,1.15-1.22,3-.07,4.18,1.12,1.16,3,1.19,4.16.09,1.18-1.13,1.22-3.01.1-4.19"/> <path class="cls-6" d="m192.67,43.01c-1.24,1.18-3.22,1.14-4.41-.1-1.16-1.22-1.12-3.2.09-4.37,1.24-1.2,3.19-1.17,4.4.08,1.2,1.24,1.17,3.21-.08,4.4m10.52-6.97c.56-.57.86-1.34.81-2.14v-.02c-.13-2.43-3.08-3.56-4.81-1.84l-2.79,2.84c-.89.89-2.95,1.03-4.01-.03l-6.67-6.75c-.53-.55-1.26-.86-2.02-.86-2.51,0-3.76,3.03-1.99,4.81l2.81,2.71c1.02,1.11.91,3.07,0,3.98l-6.75,6.77c-.52.52-.82,1.22-.82,1.96v.06c-.03,2.53,3.02,3.81,4.81,2.03l2.81-2.82c.98-.98,3.01-.99,4.03.04l6.64,6.68c.55.55,1.3.85,2.08.82h0c2.47-.07,3.65-3.06,1.91-4.81l-2.68-2.71c-.99-.99-1.07-2.91,0-3.98l6.65-6.75Z"/> </g> <g> <polygon class="cls-6" points="213.39 30.52 213.39 38.85 210.67 38.85 210.67 26.08 213.47 26.08 219.39 34.1 219.39 26.08 222.11 26.08 222.11 38.85 219.48 38.85 213.39 30.52"/> <path class="cls-6" d="m226.49,33.35h4.56c-.06-.88-.67-2.05-2.28-2.05-1.51,0-2.16,1.13-2.28,2.05m2.28-3.98c2.76,0,4.64,2.07,4.64,5.09v.54h-6.88c.15,1.17,1.09,2.14,2.66,2.14.86,0,1.88-.34,2.47-.92l1.07,1.57c-.92.84-2.37,1.28-3.81,1.28-2.82,0-4.94-1.9-4.94-4.86,0-2.68,1.97-4.85,4.79-4.85"/> <polygon class="cls-6" points="238.95 35.73 236.82 38.85 234.12 38.85 237.4 34.1 234.31 29.6 237.03 29.6 238.95 32.45 240.85 29.6 243.57 29.6 240.46 34.1 243.78 38.85 241.06 38.85 238.95 35.73"/> <path class="cls-6" d="m251.23,37.68c-.63.71-1.74,1.4-3.26,1.4-2.03,0-2.99-1.11-2.99-2.91v-6.57h2.43v5.61c0,1.28.67,1.7,1.7,1.7.94,0,1.69-.52,2.11-1.05v-6.26h2.43v9.25h-2.43v-1.17Z"/> <path class="cls-6" d="m256.32,35.94c.67.63,2.05,1.26,3.2,1.26,1.05,0,1.55-.42,1.55-1,0-.63-.84-.8-1.86-1-1.59-.31-3.64-.71-3.64-2.93,0-1.55,1.36-2.91,3.79-2.91,1.57,0,2.82.54,3.74,1.26l-.98,1.67c-.56-.59-1.61-1.07-2.74-1.07-.88,0-1.46.4-1.46.92s.73.69,1.76.9c1.59.31,3.72.75,3.72,3.06,0,1.69-1.44,2.97-4,2.97-1.61,0-3.16-.54-4.14-1.44l1.05-1.7Z"/> </g> <path class="cls-6" d="m232.28,54.6c-.63.71-1.74,1.4-3.26,1.4-2.03,0-2.99-1.11-2.99-2.91v-6.57h2.43v5.61c0,1.28.67,1.7,1.7,1.7.94,0,1.69-.52,2.11-1.05v-6.26h2.43v9.25h-2.43v-1.17Z"/> <path class="cls-6" d="m237.76,53.47v-4.83h-1.53v-2.13h1.53v-2.53h2.45v2.53h1.88v2.13h-1.88v4.18c0,.57.31,1.02.84,1.02.36,0,.71-.13.84-.27l.52,1.84c-.36.33-1.02.59-2.03.59-1.7,0-2.62-.88-2.62-2.53"/> <path class="cls-6" d="m250,54.6c-.63.71-1.74,1.4-3.26,1.4-2.03,0-2.99-1.11-2.99-2.91v-6.57h2.43v5.61c0,1.28.67,1.7,1.7,1.7.94,0,1.69-.52,2.11-1.05v-6.26h2.43v9.25h-2.43v-1.17Z"/> <path class="cls-6" d="m260.4,52.4c-.4-.54-1.17-.8-1.95-.8-.96,0-1.74.5-1.74,1.4s.78,1.36,1.74,1.36c.79,0,1.55-.27,1.95-.8v-1.15Zm0,2.41c-.63.75-1.72,1.19-2.93,1.19-1.48,0-3.22-1-3.22-3.06s1.74-2.95,3.22-2.95c1.23,0,2.32.38,2.93,1.13v-1.28c0-.94-.8-1.55-2.03-1.55-1,0-1.92.36-2.7,1.09l-.92-1.63c1.13-1,2.59-1.46,4.04-1.46,2.11,0,4.04.84,4.04,3.5v5.98h-2.43v-.96Z"/> </g> <text class="cls-7" x="7%" y="25%"><tspan>Cover Info</tspan></text> <text class="cls-8" x="7%" y="35%"><tspan>Product:</tspan></text> <text class="cls-8" x="7%" y="40%"><tspan>Amount:</tspan></text> <text class="cls-8" x="7%" y="45%"><tspan>Expiry Date: </tspan></text> <text class="cls-8" x="7%" y="50%"><tspan>Cover ID:</tspan></text> <text class="cls-9" x="93%" y="35%" text-anchor="end">', svgData ) ) ); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @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: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * 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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol) pragma solidity ^0.8.0; /** * @dev Provides a set of functions to operate with Base64 strings. * * _Available since v4.5._ */ library Base64 { /** * @dev Base64 Encoding/Decoding Table */ string internal constant _TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /** * @dev Converts a `bytes` to its Bytes64 `string` representation. */ function encode(bytes memory data) internal pure returns (string memory) { /** * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol */ if (data.length == 0) return ""; // Loads the table into memory string memory table = _TABLE; // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter // and split into 4 numbers of 6 bits. // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up // - `data.length + 2` -> Round up // - `/ 3` -> Number of 3-bytes chunks // - `4 *` -> 4 characters for each chunk string memory result = new string(4 * ((data.length + 2) / 3)); /// @solidity memory-safe-assembly assembly { // Prepare the lookup table (skip the first "length" byte) let tablePtr := add(table, 1) // Prepare result pointer, jump over length let resultPtr := add(result, 32) // Run over the input, 3 bytes at a time for { let dataPtr := data let endPtr := add(data, mload(data)) } lt(dataPtr, endPtr) { } { // Advance 3 bytes dataPtr := add(dataPtr, 3) let input := mload(dataPtr) // To write each character, shift the 3 bytes (18 bits) chunk // 4 times in blocks of 6 bits for each character (18, 12, 6, 0) // and apply logical AND with 0x3F which is the number of // the previous character in the ASCII table prior to the Base64 Table // The result is then added to the table to get the character to write, // and finally write it in the result pointer but with a left shift // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F)))) resultPtr := add(resultPtr, 1) // Advance } // When data `bytes` is not exactly 3 bytes long // it is padded with `=` characters at the end switch mod(mload(data), 3) case 1 { mstore8(sub(resultPtr, 1), 0x3d) mstore8(sub(resultPtr, 2), 0x3d) } case 2 { mstore8(sub(resultPtr, 1), 0x3d) } } return result; } }
// SPDX-License-Identifier: MIT // 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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_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) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev 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); } }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity >=0.5.0; import "./ICoverNFT.sol"; import "./IStakingNFT.sol"; import "./IStakingPool.sol"; import "./IStakingPoolFactory.sol"; /* ========== DATA STRUCTURES ========== */ enum ClaimMethod { IndividualClaims, YieldTokenIncidents } // Basically CoverStatus from QuotationData.sol but with the extra Migrated status to avoid // polluting Cover.sol state layout with new status variables. enum LegacyCoverStatus { Active, ClaimAccepted, ClaimDenied, CoverExpired, ClaimSubmitted, Requested, Migrated } /* io structs */ struct PoolAllocationRequest { uint40 poolId; bool skip; uint coverAmountInAsset; } struct RequestAllocationVariables { uint previousPoolAllocationsLength; uint previousPremiumInNXM; uint refund; uint coverAmountInNXM; } struct BuyCoverParams { uint coverId; address owner; uint24 productId; uint8 coverAsset; uint96 amount; uint32 period; uint maxPremiumInAsset; uint8 paymentAsset; uint16 commissionRatio; address commissionDestination; string ipfsData; } struct ProductParam { string productName; uint productId; string ipfsMetadata; Product product; uint[] allowedPools; } struct ProductTypeParam { string productTypeName; uint productTypeId; string ipfsMetadata; ProductType productType; } struct ProductInitializationParams { uint productId; uint8 weight; uint96 initialPrice; uint96 targetPrice; } /* storage structs */ struct PoolAllocation { uint40 poolId; uint96 coverAmountInNXM; uint96 premiumInNXM; uint24 allocationId; } struct CoverData { uint24 productId; uint8 coverAsset; uint96 amountPaidOut; } struct CoverSegment { uint96 amount; uint32 start; uint32 period; // seconds uint32 gracePeriod; // seconds uint24 globalRewardsRatio; uint24 globalCapacityRatio; } struct Product { uint16 productType; address yieldTokenAddress; // cover assets bitmap. each bit represents whether the asset with // the index of that bit is enabled as a cover asset for this product uint32 coverAssets; uint16 initialPriceRatio; uint16 capacityReductionRatio; bool isDeprecated; bool useFixedPrice; } struct ProductType { uint8 claimMethod; uint32 gracePeriod; } struct ActiveCover { // Global active cover amount per asset. uint192 totalActiveCoverInAsset; // The last time activeCoverExpirationBuckets was updated uint64 lastBucketUpdateId; } interface ICover { /* ========== VIEWS ========== */ function coverData(uint coverId) external view returns (CoverData memory); function coverDataCount() external view returns (uint); function coverSegmentsCount(uint coverId) external view returns (uint); function coverSegments(uint coverId) external view returns (CoverSegment[] memory); function coverSegmentWithRemainingAmount( uint coverId, uint segmentId ) external view returns (CoverSegment memory); function products(uint id) external view returns (Product memory); function productTypes(uint id) external view returns (ProductType memory); function stakingPool(uint index) external view returns (IStakingPool); function productNames(uint productId) external view returns (string memory); function productsCount() external view returns (uint); function productTypesCount() external view returns (uint); function totalActiveCoverInAsset(uint coverAsset) external view returns (uint); function globalCapacityRatio() external view returns (uint); function globalRewardsRatio() external view returns (uint); function getPriceAndCapacityRatios(uint[] calldata productIds) external view returns ( uint _globalCapacityRatio, uint _globalMinPriceRatio, uint[] memory _initialPriceRatios, uint[] memory _capacityReductionRatios ); /* === MUTATIVE FUNCTIONS ==== */ function addLegacyCover( uint productId, uint coverAsset, uint amount, uint start, uint period, address newOwner ) external returns (uint coverId); function buyCover( BuyCoverParams calldata params, PoolAllocationRequest[] calldata coverChunkRequests ) external payable returns (uint coverId); function setProductTypes(ProductTypeParam[] calldata productTypes) external; function setProducts(ProductParam[] calldata params) external; function burnStake( uint coverId, uint segmentId, uint amount ) external returns (address coverOwner); function coverNFT() external returns (ICoverNFT); function stakingNFT() external returns (IStakingNFT); function stakingPoolFactory() external returns (IStakingPoolFactory); function createStakingPool( bool isPrivatePool, uint initialPoolFee, uint maxPoolFee, ProductInitializationParams[] calldata productInitParams, string calldata ipfsDescriptionHash ) external returns (uint poolId, address stakingPoolAddress); function isPoolAllowed(uint productId, uint poolId) external returns (bool); /* ========== EVENTS ========== */ event ProductSet(uint id, string ipfsMetadata); event ProductTypeSet(uint id, string ipfsMetadata); event CoverEdited(uint indexed coverId, uint indexed productId, uint indexed segmentId, address buyer, string ipfsMetadata); // Auth error OnlyMemberRolesCanOperateTransfer(); error OnlyOwnerOrApproved(); // Cover details error CoverPeriodTooShort(); error CoverPeriodTooLong(); error CoverOutsideOfTheGracePeriod(); error CoverAmountIsZero(); // Products error ProductDoesntExist(); error ProductTypeNotFound(); error ProductDeprecated(); error ProductDeprecatedOrNotInitialized(); error InvalidProductType(); error UnexpectedProductId(); // Cover and payment assets error CoverAssetNotSupported(); error InvalidPaymentAsset(); error UnexpectedCoverAsset(); error UnsupportedCoverAssets(); error UnexpectedEthSent(); // Price & Commission error PriceExceedsMaxPremiumInAsset(); error TargetPriceBelowGlobalMinPriceRatio(); error InitialPriceRatioBelowGlobalMinPriceRatio(); error InitialPriceRatioAbove100Percent(); error CommissionRateTooHigh(); // ETH transfers error InsufficientEthSent(); error SendingEthToPoolFailed(); error SendingEthToCommissionDestinationFailed(); error ReturningEthRemainderToSenderFailed(); // Misc error AlreadyInitialized(); error ExpiredCoversCannotBeEdited(); error InsufficientCoverAmountAllocated(); error UnexpectedPoolId(); error CapacityReductionRatioAbove100Percent(); }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity >=0.5.0; import "@openzeppelin/contracts-v4/token/ERC721/IERC721.sol"; interface ICoverNFT is IERC721 { function isApprovedOrOwner(address spender, uint tokenId) external returns (bool); function mint(address to) external returns (uint tokenId); function changeOperator(address newOperator) external; function totalSupply() external view returns (uint); function name() external view returns (string memory); error NotOperator(); error NotMinted(); error WrongFrom(); error InvalidRecipient(); error InvalidNewOperatorAddress(); error InvalidNewNFTDescriptorAddress(); error NotAuthorized(); error UnsafeRecipient(); error AlreadyMinted(); }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity >=0.5.0; interface ICoverNFTDescriptor { function tokenURI(uint tokenId) external view returns (string memory); }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity >=0.5.0; interface IERC20Detailed { function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); function transfer(address recipient, uint256 amount) external returns (bool); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); function decimals() external view returns (uint8); function symbol() external view returns (string memory); }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity >=0.5.0; interface INXMMaster { function tokenAddress() external view returns (address); function owner() external view returns (address); function emergencyAdmin() external view returns (address); function masterInitialized() external view returns (bool); function isInternal(address _add) external view returns (bool); function isPause() external view returns (bool check); function isMember(address _add) external view returns (bool); function checkIsAuthToGoverned(address _add) external view returns (bool); function getLatestAddress(bytes2 _contractName) external view returns (address payable contractAddress); function contractAddresses(bytes2 code) external view returns (address payable); function upgradeMultipleContracts( bytes2[] calldata _contractCodes, address payable[] calldata newAddresses ) external; function removeContracts(bytes2[] calldata contractCodesToRemove) external; function addNewInternalContracts( bytes2[] calldata _contractCodes, address payable[] calldata newAddresses, uint[] calldata _types ) external; function updateOwnerParameters(bytes8 code, address payable val) external; }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity >=0.5.0; import "./IPriceFeedOracle.sol"; struct SwapDetails { uint104 minAmount; uint104 maxAmount; uint32 lastSwapTime; // 2 decimals of precision. 0.01% -> 0.0001 -> 1e14 uint16 maxSlippageRatio; } struct Asset { address assetAddress; bool isCoverAsset; bool isAbandoned; } interface IPool { function getAsset(uint assetId) external view returns (Asset memory); function getAssets() external view returns (Asset[] memory); function buyNXM(uint minTokensOut) external payable; function sellNXM(uint tokenAmount, uint minEthOut) external; function sellNXMTokens(uint tokenAmount) external returns (bool); function transferAssetToSwapOperator(address asset, uint amount) external; function setSwapDetailsLastSwapTime(address asset, uint32 lastSwapTime) external; function getAssetSwapDetails(address assetAddress) external view returns (SwapDetails memory); function getNXMForEth(uint ethAmount) external view returns (uint); function sendPayout(uint assetIndex, address payable payoutAddress, uint amount) external; function upgradeCapitalPool(address payable newPoolAddress) external; function priceFeedOracle() external view returns (IPriceFeedOracle); function getPoolValueInEth() external view returns (uint); function getEthForNXM(uint nxmAmount) external view returns (uint ethAmount); function calculateEthForNXM(uint nxmAmount, uint currentTotalAssetValue, uint mcrEth) external pure returns (uint); function calculateMCRRatio(uint totalAssetValue, uint mcrEth) external pure returns (uint); function calculateTokenSpotPrice(uint totalAssetValue, uint mcrEth) external pure returns (uint tokenPrice); function getTokenPriceInAsset(uint assetId) external view returns (uint tokenPrice); function getTokenPrice() external view returns (uint tokenPrice); function getMCRRatio() external view returns (uint); function setSwapValue(uint value) external; }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity >=0.5.0; interface Aggregator { function latestAnswer() external view returns (int); } struct OracleAsset { Aggregator aggregator; uint8 decimals; } interface IPriceFeedOracle { function ETH() external view returns (address); function assets(address) external view returns (Aggregator, uint8); function getAssetToEthRate(address asset) external view returns (uint); function getAssetForEth(address asset, uint ethIn) external view returns (uint); function getEthForAsset(address asset, uint amount) external view returns (uint); }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity >=0.5.0; import "@openzeppelin/contracts-v4/token/ERC721/IERC721.sol"; interface IStakingNFT is IERC721 { function isApprovedOrOwner(address spender, uint tokenId) external returns (bool); function mint(uint poolId, address to) external returns (uint tokenId); function changeOperator(address newOperator) external; function totalSupply() external returns (uint); function tokenInfo(uint tokenId) external view returns (uint poolId, address owner); function stakingPoolOf(uint tokenId) external view returns (uint poolId); function stakingPoolFactory() external view returns (address); function name() external view returns (string memory); error NotOperator(); error NotMinted(); error WrongFrom(); error InvalidRecipient(); error InvalidNewOperatorAddress(); error InvalidNewNFTDescriptorAddress(); error NotAuthorized(); error UnsafeRecipient(); error AlreadyMinted(); error NotStakingPool(); }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity >=0.5.0; /* structs for io */ struct AllocationRequest { uint productId; uint coverId; uint allocationId; uint period; uint gracePeriod; bool useFixedPrice; uint previousStart; uint previousExpiration; uint previousRewardsRatio; uint globalCapacityRatio; uint capacityReductionRatio; uint rewardRatio; uint globalMinPrice; } struct StakedProductParam { uint productId; bool recalculateEffectiveWeight; bool setTargetWeight; uint8 targetWeight; bool setTargetPrice; uint96 targetPrice; } struct BurnStakeParams { uint allocationId; uint productId; uint start; uint period; uint deallocationAmount; } interface IStakingPool { /* structs for storage */ // stakers are grouped in tranches based on the timelock expiration // tranche index is calculated based on the expiration date // the initial proposal is to have 4 tranches per year (1 tranche per quarter) struct Tranche { uint128 stakeShares; uint128 rewardsShares; } struct ExpiredTranche { uint96 accNxmPerRewardShareAtExpiry; uint96 stakeAmountAtExpiry; // nxm total supply is 6.7e24 and uint96.max is 7.9e28 uint128 stakeSharesSupplyAtExpiry; } struct Deposit { uint96 lastAccNxmPerRewardShare; uint96 pendingRewards; uint128 stakeShares; uint128 rewardsShares; } function initialize( bool isPrivatePool, uint initialPoolFee, uint maxPoolFee, uint _poolId, string memory ipfsDescriptionHash ) external; function processExpirations(bool updateUntilCurrentTimestamp) external; function requestAllocation( uint amount, uint previousPremium, AllocationRequest calldata request ) external returns (uint premium, uint allocationId); function burnStake(uint amount, BurnStakeParams calldata params) external; function depositTo( uint amount, uint trancheId, uint requestTokenId, address destination ) external returns (uint tokenId); function withdraw( uint tokenId, bool withdrawStake, bool withdrawRewards, uint[] memory trancheIds ) external returns (uint withdrawnStake, uint withdrawnRewards); function isPrivatePool() external view returns (bool); function isHalted() external view returns (bool); function manager() external view returns (address); function getPoolId() external view returns (uint); function getPoolFee() external view returns (uint); function getMaxPoolFee() external view returns (uint); function getActiveStake() external view returns (uint); function getStakeSharesSupply() external view returns (uint); function getRewardsSharesSupply() external view returns (uint); function getRewardPerSecond() external view returns (uint); function getAccNxmPerRewardsShare() external view returns (uint); function getLastAccNxmUpdate() external view returns (uint); function getFirstActiveTrancheId() external view returns (uint); function getFirstActiveBucketId() external view returns (uint); function getNextAllocationId() external view returns (uint); function getDeposit(uint tokenId, uint trancheId) external view returns ( uint lastAccNxmPerRewardShare, uint pendingRewards, uint stakeShares, uint rewardsShares ); function getTranche(uint trancheId) external view returns ( uint stakeShares, uint rewardsShares ); function getExpiredTranche(uint trancheId) external view returns ( uint accNxmPerRewardShareAtExpiry, uint stakeAmountAtExpiry, uint stakeShareSupplyAtExpiry ); function setPoolFee(uint newFee) external; function setPoolPrivacy(bool isPrivatePool) external; function getActiveAllocations( uint productId ) external view returns (uint[] memory trancheAllocations); function getTrancheCapacities( uint productId, uint firstTrancheId, uint trancheCount, uint capacityRatio, uint reductionRatio ) external view returns (uint[] memory trancheCapacities); /* ========== EVENTS ========== */ event StakeDeposited(address indexed user, uint256 amount, uint256 trancheId, uint256 tokenId); event DepositExtended(address indexed user, uint256 tokenId, uint256 initialTrancheId, uint256 newTrancheId, uint256 topUpAmount); event PoolPrivacyChanged(address indexed manager, bool isPrivate); event PoolFeeChanged(address indexed manager, uint newFee); event PoolDescriptionSet(string ipfsDescriptionHash); event Withdraw(address indexed user, uint indexed tokenId, uint tranche, uint amountStakeWithdrawn, uint amountRewardsWithdrawn); event StakeBurned(uint amount); // Auth error OnlyCoverContract(); error OnlyManager(); error PrivatePool(); error SystemPaused(); error PoolHalted(); // Fees error PoolFeeExceedsMax(); error MaxPoolFeeAbove100(); // Voting error NxmIsLockedForGovernanceVote(); error ManagerNxmIsLockedForGovernanceVote(); // Deposit error InsufficientDepositAmount(); error RewardRatioTooHigh(); // Staking NFTs error InvalidTokenId(); error NotTokenOwnerOrApproved(); error InvalidStakingPoolForToken(); // Tranche & capacity error NewTrancheEndsBeforeInitialTranche(); error RequestedTrancheIsNotYetActive(); error RequestedTrancheIsExpired(); error InsufficientCapacity(); }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity >=0.5.0; interface IStakingPoolFactory { function stakingPoolCount() external view returns (uint); function beacon() external view returns (address); function create(address beacon) external returns (uint poolId, address stakingPoolAddress); event StakingPoolCreated(uint indexed poolId, address indexed stakingPoolAddress); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; // Modified from: https://github.com/bokkypoobah/BokkyPooBahsDateTimeLibrary/blob/master/contracts/BokkyPooBahsDateTimeLibrary.sol library DateTime { uint constant SECONDS_PER_MINUTE = 60; uint constant SECONDS_PER_HOUR = SECONDS_PER_MINUTE * SECONDS_PER_MINUTE; uint constant SECONDS_PER_DAY = 24 * SECONDS_PER_HOUR; int constant OFFSET19700101 = 2440588; function _daysToDate(uint _days) internal pure returns (uint year, uint month, uint day) { int __days = int(_days); int L = __days + 68569 + OFFSET19700101; int N = 4 * L / 146097; L = L - (146097 * N + 3) / 4; int _year = 4000 * (L + 1) / 1461001; L = L - 1461 * _year / 4 + 31; int _month = 80 * L / 2447; int _day = L - 2447 * _month / 80; L = _month / 11; _month = _month + 2 - 12 * L; _year = 100 * (N - 49) + _year + L; year = uint(_year); month = uint(_month); day = uint(_day); } function timestampToDate(uint timestamp) internal pure returns (uint year, uint month, uint day) { (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY); } function getMonthString(uint month) internal pure returns (string memory) { if (month == 1) { return "Jan"; } if (month == 2) { return "Feb"; } if (month == 3) { return "Mar"; } if (month == 4) { return "Apr"; } if (month == 5) { return "May"; } if (month == 6) { return "Jun"; } if (month == 7) { return "Jul"; } if (month == 8) { return "Aug"; } if (month == 9) { return "Sep"; } if (month == 10) { return "Oct"; } if (month == 11) { return "Nov"; } if (month == 12) { return "Dec"; } revert("Invalid month"); } }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.0; import "@openzeppelin/contracts-v4/utils/Strings.sol"; library FloatingPoint { using Strings for uint; // Convert a number to a float string with 2 decimals function toFloat( uint number, uint decimals ) internal pure returns (string memory float) { if (decimals == 0) { return string(abi.encodePacked(number.toString(), ".00")); } uint decimalBase = 10 ** decimals; // Get the integer part uint integerVal = number / (decimalBase); float = string(abi.encodePacked(integerVal.toString(), ".")); // Get the remainder uint remainder = number % (decimalBase); string memory remainderStr = remainder.toString(); bytes memory remainderBytes = bytes(remainderStr); // The number of digits should be greater than decimals - 1 if (remainderBytes.length + 1 < decimals) { return string(abi.encodePacked(float, "00")); } // If the remainder is less than 10, add a leading zero before digit and return if (remainder < decimalBase / 10) { remainderStr = string(abi.encodePacked("0", remainderBytes[0])); return string(abi.encodePacked(float, remainderStr)); } // If the remainder is a single digit, add a trailing zero and return if (remainderBytes.length == 1) { remainderStr = string(abi.encodePacked(remainderBytes[0], "0")); return string(abi.encodePacked(float, remainderStr)); } // Otherwise encode first two digits of remainder remainderStr = string( abi.encodePacked(remainderBytes[0], remainderBytes[1]) ); float = string(abi.encodePacked(float, remainderStr)); } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity ^0.8.18; import "../../interfaces/ICoverNFT.sol"; import "../../interfaces/ICoverNFTDescriptor.sol"; /// @dev Based on Solmate https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol contract CoverNFT is ICoverNFT { string public name; string public symbol; mapping(uint => address) internal _ownerOf; mapping(address => uint) internal _balanceOf; mapping(uint => address) public getApproved; mapping(address => mapping(address => bool)) public isApprovedForAll; uint96 internal _totalSupply; address public operator; address public nftDescriptor; modifier onlyOperator { if (msg.sender != operator) revert NotOperator(); _; } constructor( string memory _name, string memory _symbol, address _operator, address _nftDescriptor ) { name = _name; symbol = _symbol; operator = _operator; nftDescriptor = _nftDescriptor; } // operator functions function changeOperator(address _newOperator) public onlyOperator { if (_newOperator == address(0)) revert InvalidNewOperatorAddress(); operator = _newOperator; } function changeNFTDescriptor(address _newNFTDescriptor) public onlyOperator { if (_newNFTDescriptor == address(0)) revert InvalidNewNFTDescriptorAddress(); nftDescriptor = _newNFTDescriptor; } // minting and supply function mint(address to) external onlyOperator returns (uint id) { if (to == address(0)) revert InvalidRecipient(); // counter overflow is incredibly unrealistic unchecked { id = ++_totalSupply; _balanceOf[to]++; } _ownerOf[id] = to; emit Transfer(address(0), to, id); } function totalSupply() public view returns (uint) { return _totalSupply; } // ERC165 function supportsInterface(bytes4 interfaceId) public pure returns (bool) { return interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165 interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721 interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata } // ERC721 function tokenURI(uint id) public view virtual returns (string memory uri) { if (_ownerOf[id] == address(0)) revert NotMinted(); return ICoverNFTDescriptor(nftDescriptor).tokenURI(id); } function ownerOf(uint id) public view returns (address owner) { if ((owner = _ownerOf[id]) == address(0)) revert NotMinted(); } function balanceOf(address owner) public view returns (uint) { if (owner == address(0)) revert NotMinted(); return _balanceOf[owner]; } function approve(address spender, uint id) public { address owner = _ownerOf[id]; if (msg.sender != owner && !isApprovedForAll[owner][msg.sender]) revert NotAuthorized(); getApproved[id] = spender; emit Approval(owner, spender, id); } function setApprovalForAll(address spender, bool approved) public { isApprovedForAll[msg.sender][spender] = approved; emit ApprovalForAll(msg.sender, spender, approved); } /// @dev `ownerOf` and `getApproved` throw if the token doesn't exist as per ERC721 spec /// @dev as a consequence this function will throw as well in that case function isApprovedOrOwner(address spender, uint tokenId) external view returns (bool) { address owner = ownerOf(tokenId); return spender == owner || isApprovedForAll[owner][spender] || spender == getApproved[tokenId]; } function transferFrom(address from, address to, uint id) public { if (from != _ownerOf[id]) revert WrongFrom(); if (to == address(0)) revert InvalidRecipient(); if (msg.sender != from && !isApprovedForAll[from][msg.sender] && msg.sender != getApproved[id]) { revert NotAuthorized(); } // underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow unchecked { _balanceOf[from]--; _balanceOf[to]++; } _ownerOf[id] = to; delete getApproved[id]; emit Transfer(from, to, id); } function safeTransferFrom(address from, address to, uint id) public { transferFrom(from, to, id); if (to.code.length != 0 && ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, "") != ERC721TokenReceiver.onERC721Received.selector) { revert UnsafeRecipient(); } } function safeTransferFrom( address from, address to, uint id, bytes calldata data ) public { transferFrom(from, to, id); if (to.code.length != 0 && ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) != ERC721TokenReceiver.onERC721Received.selector) { revert UnsafeRecipient(); } } } /// @notice A generic interface for a contract which properly accepts ERC721 tokens. /// @dev Based on (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol) abstract contract ERC721TokenReceiver { function onERC721Received(address, address, uint, bytes calldata) external virtual returns (bytes4) { return ERC721TokenReceiver.onERC721Received.selector; } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract INXMMaster","name":"_master","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"addZeroPrefix","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"generateDescription","outputs":[{"internalType":"string","name":"descriptionString","type":"string"},{"components":[{"internalType":"string","name":"productName","type":"string"},{"internalType":"string","name":"assetSymbol","type":"string"},{"internalType":"string","name":"expiryDate","type":"string"},{"internalType":"uint256","name":"coverAmount","type":"uint256"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"decimals","type":"uint256"}],"internalType":"struct CoverNFTDescriptor.CoverDescription","name":"descriptionData","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"productName","type":"string"},{"internalType":"string","name":"assetSymbol","type":"string"},{"internalType":"string","name":"expiryDate","type":"string"},{"internalType":"uint256","name":"coverAmount","type":"uint256"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"decimals","type":"uint256"}],"internalType":"struct CoverNFTDescriptor.CoverDescription","name":"descriptionData","type":"tuple"}],"name":"generateSVGImage","outputs":[{"internalType":"bytes","name":"image","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"assetId","type":"uint256"}],"name":"getAssetDecimals","outputs":[{"internalType":"uint256","name":"decimals","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assetId","type":"uint256"}],"name":"getAssetSymbol","outputs":[{"internalType":"string","name":"assetSymbol","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"master","outputs":[{"internalType":"contract INXMMaster","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60a06040523480156200001157600080fd5b506040516200429638038062004296833981016040819052620000349162000046565b6001600160a01b031660805262000078565b6000602082840312156200005957600080fd5b81516001600160a01b03811681146200007157600080fd5b9392505050565b6080516141ed620000a96000396000818161010a015281816102050152818161079901526109fe01526141ed6000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c80636f9759811161005b5780636f975981146100df578063c87b56dd146100f2578063ee97f7f314610105578063f6de23601461014457600080fd5b806322a3560a146100825780632409145e146100ab5780634e6d052d146100cc575b600080fd5b610095610090366004611399565b610165565b6040516100a29190611402565b60405180910390f35b6100be6100b9366004611399565b6101ae565b6040516100a292919061141c565b6100956100da3660046115bb565b6106b8565b6100956100ed366004611399565b610754565b610095610100366004611399565b6108ef565b61012c7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016100a2565b610157610152366004611399565b6109d0565b6040519081526020016100a2565b6060600a82101561019f5761017982610b53565b60405160200161018991906116ad565b6040516020818303038152906040529050919050565b6101a882610b53565b92915050565b60606101e96040518060c001604052806060815260200160608152602001606081526020016000815260200160008152602001600081525090565b6040516227050b60e31b815261434f60f01b60048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690630138285890602401602060405180830381865afa158015610254573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061027891906116ee565b905083816001600160a01b031663404730f46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102dd919061170b565b101561036b5750506040805160e081018252600060c082018181528252825160208181018552828252808401919091528351808201855282815283850152606083018290526080830182905260a08301919091528251808401909352601783527f54686973204e465420646f6573206e6f742065786973740000000000000000009083015290939092509050565b60405163bce2a88360e01b8152600481018590526000906001600160a01b0383169063bce2a88390602401606060405180830381865afa1580156103b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d79190611764565b80516040516372ca814160e11b815262ffffff90911660048201529091506000906001600160a01b0384169063e595028290602401600060405180830381865afa158015610429573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261045191908101906117b2565b90506000836001600160a01b031663ccfa4b79886001876001600160a01b031663638233088c6040518263ffffffff1660e01b815260040161049591815260200190565b602060405180830381865afa1580156104b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104d6919061170b565b6104e0919061183f565b6040516001600160e01b031960e085901b1681526004810192909252602482015260440160c060405180830381865afa158015610521573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105459190611866565b90506060428260400151836020015161055e91906118e7565b63ffffffff1611610585576040518060600160405280602281526020016141966022913990505b606060008060006105ae866040015187602001516105a391906118e7565b63ffffffff16610c54565b9250925092506105bd82610c8d565b6105c682610165565b6105cf85610b53565b6040516020016105e19392919061190b565b60405160208183030381529060405293505050508361061c84600001516001600160601b0316610617886020015160ff166109d0565b610e9f565b61062c876020015160ff16610754565b8385604051602001610642959493929190611965565b60405160208183030381529060405297506040518060c00160405280858152602001610674876020015160ff16610754565b815260200182815260200184600001516001600160601b031681526020018a81526020016106a8876020015160ff166109d0565b8152509650505050505050915091565b6060600082600001516106d384606001518560a00151610e9f565b846020015185604001516106ea8760800151610b53565b6040516020016106fe959493929190611a6b565b6040516020818303038152906040529050806040516020016107209190611c5e565b60408051601f198184030181529082905261073d91602001613ce6565b604051602081830303815290604052915050919050565b60608160000361077d57505060408051808201909152600381526208aa8960eb1b602082015290565b6040516227050b60e31b815261503160f01b60048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690630138285890602401602060405180830381865afa1580156107e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080c91906116ee565b604051631d591eb760e31b8152600481018590529091506000906001600160a01b0383169063eac8f5b890602401606060405180830381865afa158015610857573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061087b9190613d12565b905080600001516001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa1580156108bf573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108e791908101906117b2565b949350505050565b60606000806108fd846101ae565b91509150600061091461090f836106b8565b6110d2565b90506109a7336001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa158015610957573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261097f91908101906117b2565b848360405160200161099393929190613d56565b6040516020818303038152906040526110d2565b6040516020016109b79190613e27565b6040516020818303038152906040529350505050919050565b6000816000036109e257506012919050565b6040516227050b60e31b815261503160f01b60048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690630138285890602401602060405180830381865afa158015610a4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a7191906116ee565b604051631d591eb760e31b8152600481018590529091506000906001600160a01b0383169063eac8f5b890602401606060405180830381865afa158015610abc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ae09190613d12565b905080600001516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b489190613e6c565b60ff16949350505050565b606081600003610b7a5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ba45780610b8e81613e87565b9150610b9d9050600a83613eb6565b9150610b7e565b60008167ffffffffffffffff811115610bbf57610bbf6114aa565b6040519080825280601f01601f191660200182016040528015610be9576020820181803683370190505b5090505b84156108e757610bfe60018361183f565b9150610c0b600a86613eca565b610c16906030613ede565b60f81b818381518110610c2b57610c2b613ef1565b60200101906001600160f81b031916908160001a905350610c4d600a86613eb6565b9450610bed565b60008080610c80610c66603c80613f07565b610c71906018613f07565b610c7b9086613eb6565b611225565b9196909550909350915050565b606081600103610cb65750506040805180820190915260038152622530b760e91b602082015290565b81600203610cdd5750506040805180820190915260038152622332b160e91b602082015290565b81600303610d0457505060408051808201909152600381526226b0b960e91b602082015290565b81600403610d2b57505060408051808201909152600381526220b83960e91b602082015290565b81600503610d525750506040805180820190915260038152624d617960e81b602082015290565b81600603610d79575050604080518082019091526003815262253ab760e91b602082015290565b81600703610da0575050604080518082019091526003815262129d5b60ea1b602082015290565b81600803610dc757505060408051808201909152600381526241756760e81b602082015290565b81600903610dee57505060408051808201909152600381526205365760ec1b602082015290565b81600a03610e1557505060408051808201909152600381526213d8dd60ea1b602082015290565b81600b03610e3c5750506040805180820190915260038152622737bb60e91b602082015290565b81600c03610e6357505060408051808201909152600381526244656360e81b602082015290565b60405162461bcd60e51b815260206004820152600d60248201526c092dcecc2d8d2c840dadedce8d609b1b604482015260640160405180910390fd5b606081600003610ed857610eb283610b53565b604051602001610ec29190613f1e565b60405160208183030381529060405290506101a8565b6000610ee583600a614029565b90506000610ef38286613eb6565b9050610efe81610b53565b604051602001610f0e9190614035565b60408051601f1981840301815291905292506000610f2c8387613eca565b90506000610f3982610b53565b805190915081908790610f4d906001613ede565b1015610f7f5785604051602001610f64919061405a565b604051602081830303815290604052955050505050506101a8565b610f8a600a86613eb6565b831015610ff15780600081518110610fa457610fa4613ef1565b01602090810151604051600360fc1b928101929092526001600160f81b03191660218201526022015b60405160208183030381529060405291508582604051602001610f64929190614080565b805160010361103c578060008151811061100d5761100d613ef1565b016020908101516040516001600160f81b031990911691810191909152600360fc1b6021820152602201610fcd565b8060008151811061104f5761104f613ef1565b602001015160f81c60f81b8160018151811061106d5761106d613ef1565b60209101810151604080516001600160f81b0319948516938101939093529216602182015281516002818303018152602282019092529092506110b69087908490604201614080565b6040516020818303038152906040529550505050505092915050565b606081516000036110f157505060408051602081019091526000815290565b600060405180606001604052806040815260200161415660409139905060006003845160026111209190613ede565b61112a9190613eb6565b611135906004613f07565b67ffffffffffffffff81111561114d5761114d6114aa565b6040519080825280601f01601f191660200182016040528015611177576020820181803683370190505b509050600182016020820185865187015b808210156111e3576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250611188565b50506003865106600181146111ff57600281146112125761121a565b603d6001830353603d600283035361121a565b603d60018303535b509195945050505050565b60008080838162253d8c61123c8362010bd96140af565b61124691906140af565b9050600062023ab16112598360046140d7565b6112639190614107565b905060046112748262023ab16140d7565b61127f9060036140af565b6112899190614107565b6112939083614135565b9150600062164b096112a68460016140af565b6112b290610fa06140d7565b6112bc9190614107565b905060046112cc826105b56140d7565b6112d69190614107565b6112e09084614135565b6112eb90601f6140af565b9250600061098f6112fd8560506140d7565b6113079190614107565b9050600060506113198361098f6140d7565b6113239190614107565b61132d9086614135565b905061133a600b83614107565b945061134785600c6140d7565b6113528360026140af565b61135c9190614135565b9150848361136b603187614135565b6113769060646140d7565b61138091906140af565b61138a91906140af565b9a919950975095505050505050565b6000602082840312156113ab57600080fd5b5035919050565b60005b838110156113cd5781810151838201526020016113b5565b50506000910152565b600081518084526113ee8160208601602086016113b2565b601f01601f19169290920160200192915050565b60208152600061141560208301846113d6565b9392505050565b60408152600061142f60408301856113d6565b8281036020840152835160c0825261144a60c08301826113d6565b90506020850151828203602084015261146382826113d6565b9150506040850151828203604084015261147d82826113d6565b915050606085015160608301526080850151608083015260a085015160a083015280925050509392505050565b634e487b7160e01b600052604160045260246000fd5b60405160c0810167ffffffffffffffff811182821017156114e3576114e36114aa565b60405290565b6040516060810167ffffffffffffffff811182821017156114e3576114e36114aa565b604051601f8201601f1916810167ffffffffffffffff81118282101715611535576115356114aa565b604052919050565b600067ffffffffffffffff821115611557576115576114aa565b50601f01601f191660200190565b600082601f83011261157657600080fd5b81356115896115848261153d565b61150c565b81815284602083860101111561159e57600080fd5b816020850160208301376000918101602001919091529392505050565b6000602082840312156115cd57600080fd5b813567ffffffffffffffff808211156115e557600080fd5b9083019060c082860312156115f957600080fd5b6116016114c0565b82358281111561161057600080fd5b61161c87828601611565565b82525060208301358281111561163157600080fd5b61163d87828601611565565b60208301525060408301358281111561165557600080fd5b61166187828601611565565b604083015250606083013560608201526080830135608082015260a083013560a082015280935050505092915050565b600081516116a38185602086016113b2565b9290920192915050565b600360fc1b8152600082516116c98160018501602087016113b2565b9190910160010192915050565b6001600160a01b03811681146116eb57600080fd5b50565b60006020828403121561170057600080fd5b8151611415816116d6565b60006020828403121561171d57600080fd5b5051919050565b805162ffffff8116811461173757600080fd5b919050565b805160ff8116811461173757600080fd5b80516001600160601b038116811461173757600080fd5b60006060828403121561177657600080fd5b61177e6114e9565b61178783611724565b81526117956020840161173c565b60208201526117a66040840161174d565b60408201529392505050565b6000602082840312156117c457600080fd5b815167ffffffffffffffff8111156117db57600080fd5b8201601f810184136117ec57600080fd5b80516117fa6115848261153d565b81815285602083850101111561180f57600080fd5b6118208260208301602086016113b2565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b818103818111156101a8576101a8611829565b805163ffffffff8116811461173757600080fd5b600060c0828403121561187857600080fd5b6118806114c0565b6118898361174d565b815261189760208401611852565b60208201526118a860408401611852565b60408201526118b960608401611852565b60608201526118ca60808401611724565b60808201526118db60a08401611724565b60a08201529392505050565b63ffffffff81811683821601908082111561190457611904611829565b5092915050565b6000845161191d8184602089016113b2565b8083019050600160fd1b808252855161193d816001850160208a016113b2565b600192019182015283516119588160028401602088016113b2565b0160020195945050505050565b7f54686973204e465420726570726573656e7473206120636f76657220707572638152600060206e03430b9b29036b0b232903337b91d1608d1b8184015287516119b581602f8601848c016113b2565b720102e3720b6b7bab73a1021b7bb32b932b21d1606d1b602f9185019182015287516119e78160428401858c016113b2565b600160fd1b604292909101918201528651611a088160438401858b016113b2565b6f0102e3722bc3834b93c902230ba329d160851b604392909101918201528551611a388160538401858a016113b2565b62102e3760e91b605392909101918201528451611a5b81605684018589016113b2565b0160560198975050505050505050565b6000661e3a39b830b71f60c91b8083528751611a8e816007860160208c016113b2565b7f3c2f747370616e3e3c2f746578743e20203c7465787420636c6173733d22636c6007918501918201527f732d392220783d223933252220793d223430252220746578742d616e63686f726027820152661e9132b732111f60c91b6047820152604e810191909152865190611b0a826055830160208b016113b2565b818101915050600160fd1b60558201528551611b2d816056840160208a016113b2565b611c51611c28611c22611bd3611bb8611bb2611b636056888a01016e1e17ba39b830b71f1e17ba32bc3a1f60891b8152600f0190565b7f3c7465787420636c6173733d22636c732d392220783d223933252220793d223481527f35252220746578742d616e63686f723d22656e64223e3c747370616e3e0000006020820152603d0190565b8b611691565b6e1e17ba39b830b71f1e17ba32bc3a1f60891b8152600f0190565b7f3c7465787420636c6173733d22636c732d392220783d223933252220793d223581527f30252220746578742d616e63686f723d22656e64223e3c747370616e3e0000006020820152603d0190565b87611691565b7f3c2f747370616e3e3c2f746578743e20203c2f673e3c2f7376673e00000000008152601b0190565b9998505050505050505050565b7f3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323081527f30302f7376672220786d6c6e733a786c696e6b3d22687474703a2f2f7777772e60208201527f77332e6f72672f313939392f786c696e6b222076696577426f783d223020302060408201527f32393020353030223e20203c646566733e202020203c7374796c653e2020202060608201527f20202e636c732d31207b2066696c6c3a206e6f6e653b207d2020202020202e6360808201527f6c732d33207b20636c69702d706174683a2075726c2823637031293b207d202060a08201527f202020202e636c732d34207b206f7061636974793a202e30343b207d2020202060c08201527f20202e636c732d35207b2066696c6c3a20233035353033373b207d202020202060e08201527f202e636c732d362c202e636c732d372c202e636c732d382c202e636c732d39206101008201527f7b2066696c6c3a20236666663b207d2020202020202e636c732d37207b20666f6101208201527f6e742d73697a653a20313870783b207d2020202020202e636c732d372c202e636101408201527f6c732d382c202e636c732d39207b20666f6e742d66616d696c793a20417269616101608201527f6c4d542c20417269616c2c2073616e732d73657269663b207d2020202020202e6101808201527f636c732d39207b20636c69702d706174683a2075726c2823637032293b207d206101a08201527f20202020202e636c732d382c202e636c732d39207b20666f6e742d73697a653a6101c08201527f20313370783b207d202020203c2f7374796c653e202020203c636c69705061746101e08201527f682069643d22637031223e2020202020203c7265637420636c6173733d22636c6102008201527f732d31222077696474683d2232393022206865696768743d22353030222072786102208201527f3d2233322e3734222072793d2233322e3734222f3e202020203c2f636c6970506102408201527f6174683e202020203c636c6970506174682069643d22637032223e20202020206102608201527f203c7265637420636c6173733d22636c732d312220783d222d3338322e3138226102808201527f20793d222d3930222077696474683d223936382e383522206865696768743d226102a08201527f393731222f3e202020203c2f636c6970506174683e20203c2f646566733e20206102c08201527f3c673e202020203c7265637420636c6173733d22636c732d352220793d2230226102e08201527f2077696474683d2232393022206865696768743d22353030222072783d2233326103008201527f2e3734222072793d2233322e3734222f3e202020203c673e2020202020203c706103208201527f61746820636c6173733d22636c732d362220643d226d3133372e36352c3334346103408201527f2e323963352e39372d352e37362c362e31342d31352e32362e33382d32312e326103608201527f33732d31352e32362d362e31342d32312e32332d2e33382d362e31342c31352e6103808201527f32362d2e33382c32312e323363352e37362c352e39372c31352e32362c362e316103a08201527f342c32312e32332e33385a222f3e2020202020203c7061746820636c6173733d6103c082018190527f22636c732d362220643d226d35352e38352c3338322e383463352e39372d352e6103e08301527f37362c362e31342d31352e32362e33382d32312e3233732d31352e32362d362e6104008301527f31342d32312e32332d2e3338632d352e39372c352e37362d362e31342c31352e6104208301527f32362d2e33382c32312e32332c352e37362c352e39372c31352e32362c362e316104408301526104608201527f22636c732d362220643d226d39352e322c3434332e3535632d352e37382d352e6104808201527f39352d31352e32382d362e30392d32312e32332d2e33312d352e39322c352e376104a08201527f352d362e30392c31352e322d2e33382c32312e3136683063352e372c362e30326104c08201527f2c31352e322c362e32382c32312e32332e35382c362e30322d352e372c362e326104e08201527f382d31352e322e35382d32312e32332d2e30362d2e30372d2e31332d2e31342d6105008201527f2e322d2e325a222f3e2020202020203c7061746820636c6173733d22636c732d6105208201527f362220643d226d3137362e33382c3430342e3339632d352e37362d352e39372d6105408201527f31352e32362d362e31342d32312e32332d2e33382d352e39372c352e37362d366105608201527f2e31342c31352e32362d2e33382c32312e32332c352e37362c352e39372c31356105808201527f2e32362c362e31342c32312e32332e33382c352e39372d352e37362c362e31346105a08201527f2d31352e32362e33382d32312e32335a222f3e2020202020203c7061746820636105c08201527f6c6173733d22636c732d362220643d226d3137302e322c3336392e343163322e6105e08201527f38352d322e38372c342e33352d362e38322c342e31332d31302e3836762d2e316106008201527f31632d2e36382d31322e33342d31352e36352d31382e30372d32342e33392d396106208201527f2e33336c2d31342e31352c31342e34632d342e35332c342e35332d31352c352e6106408201527f32322d32302e33372d2e31366c2d33332e38342d33342e3234632d322e36392d6106608201527f322e37382d362e342d342e33352d31302e32372d342e33352d31322e37342c306106808201527f2d31392e31312c31352e342d31302e312c32342e34316c31342e32372c31332e6106a08201527f373763352e31392c352e36352c342e36322c31352e362c302c32302e32326c2d6106c08201527f33342e32382c33342e3335632d322e36342c322e36342d342e31342c362e32316106e08201527f2d342e31392c392e3934762e3332632d2e31352c31322e38322c31352e33342c6107008201527f31392e33342c32342e342c31302e32386c31342e32342d31342e333163342e396107208201527f362d342e39362c31352e32372d352e30312c32302e34362e31386c33332e372c6107408201527f33332e3963322e37392c322e37392c362e362c342e332c31302e35332c342e316107608201527f38682e30356331322e35332d2e33372c31382e35352d31352e35342c392e36396107808201527f2d32342e346c2d31332e36312d31332e3735632d352e30352d352e30352d352e6107a08201527f34332d31342e37392d2e30332d32302e31396c33332e37372d33342e32355a6d6107c08201527f2d35332e34322c33352e3338632d362e32372c362e30352d31362e32362c352e6107e08201527f38372d32322e33322d2e342d362e30352d362e32372d352e38372d31362e32366108008201527f2e342d32322e33322c362e32372d362e30352c31362e32362d352e38372c32326108208201527f2e33322e342c362e30352c362e32372c352e38372c31362e32362d2e342c32326108408201527f2e33325a222f3e202020203c2f673e202020203c7265637420636c6173733d226108608201527f636c732d31222077696474683d2232393022206865696768743d2235303022206108808201527f72783d2233322e3734222072793d2233322e3734222f3e202020203c6720636c6108a08201527f6173733d22636c732d34223e2020202020203c6720636c6173733d22636c732d6108c08201527f33223e20202020202020203c6720636c6173733d22636c732d39223e202020206108e08201527f2020202020203c7061746820636c6173733d22636c732d362220643d226d31366109008201527f362e32312c3139392e35374c302c33312e3431763436382e3539683237392e346109208201527f3263322e30362d382e33382c352e32342d31362e34372c392e35382d32332e396109408201527f33563230372e3736632d33322e32392c32322e35342d39312e31372c32332e346109608201527f342d3132322e37392d382e31385a6d382e37382c3236372e3235632d34302e346109808201527f352c33392e30332d3130342e38382c33372e38382d3134332e39322d322e35376109a08201527f2d33392e30332d34302e34352d33372e38382d3130342e38382c322e35372d316109c08201527f34332e39322c34302e34352d33392e30332c3130342e38382d33372e38382c316109e08201527f34332e39322c322e35372c33392e30332c34302e34352c33372e38382c313034610a008201527f2e38382d322e35372c3134332e39325a222f3e202020202020202020203c7061610a208201527f746820636c6173733d22636c732d362220643d226d3239302c30682d3134342e610a408201527f3234632d312e39322c32362e34382c362e39392c35332e36342c32362e38382c610a608201527f37342e32362c33312e33322c33322e34362c37392e38352c33382e33322c3131610a808201527f372e33362c31372e303756305a222f3e20202020202020203c2f673e20202020610aa08201527f20203c2f673e202020203c2f673e202020203c673e2020202020203c706f6c79610ac08201527f676f6e20636c6173733d22636c732d362220706f696e74733d223232312e3136610ae08201527f2034362e3639203231372e37362035352e3737203231362e36342035352e3737610b008201527f203231332e32342034362e3639203231332e32342035352e3737203231302e36610b208201527f372035352e3737203231302e36372034332e3238203231342e32372034332e32610b408201527f38203231372e322035302e3634203232302e31332034332e3238203232332e37610b608201527f352034332e3238203232332e37352035352e3737203232312e31362035352e37610b808201527f37203232312e31362034362e3639222f3e2020202020203c7265637420636c61610ba08201527f73733d22636c732d362220783d223236352e32352220793d2234322e39392220610bc08201527f77696474683d22322e343322206865696768743d2231322e3738222f3e202020610be08201527f2020203c673e20202020202020203c7061746820636c6173733d22636c732d36610c008201527f2220643d226d3230342e33342c34372e313163312e31382d312e31332c312e32610c208201527f322d332c2e30382d342e31382d312e31352d312e31382d332d312e32322d342e610c408201527f31382d2e30372d312e31362c312e31322d312e31392c332d2e30392c342e3136610c608201527f2c312e31332c312e31382c332e30312c312e32322c342e31392e31222f3e2020610c808201527f2020202020203c7061746820636c6173733d22636c732d362220643d226d3138610ca08201527f342e31362c35342e373563312e31332c312e31382c332c312e32322c342e3138610cc08201527f2e30382c312e31382d312e31352c312e32322d332c2e30372d342e31382d312e610ce08201527f31322d312e31362d332d312e31392d342e31362d2e30392d312e31382c312e31610d008201527f332d312e32322c332e30312d2e312c342e3139222f3e20202020202020203c70610d208201527f61746820636c6173733d22636c732d362220643d226d3137362e35362c33342e610d408201527f3433632d312e31382c312e31332d312e32322c332d2e30382c342e31382c312e610d608201527f31352c312e31382c332c312e32322c342e31382e30372c312e31362d312e3132610d808201527f2c312e31392d332c2e30392d342e31362d312e31332d312e31382d332e30312d610da08201527f312e32322d342e31392d2e31222f3e20202020202020203c7061746820636c61610dc08201527f73733d22636c732d362220643d226d3139362e38362c32362e3931632d312e31610de08201527f332d312e31382d332d312e32322d342e31382d2e30382d312e31382c312e3135610e008201527f2d312e32322c332d2e30372c342e31382c312e31322c312e31362c332c312e31610e208201527f392c342e31362e30392c312e31382d312e31332c312e32322d332e30312e312d610e408201527f342e3139222f3e20202020202020203c7061746820636c6173733d22636c732d610e608201527f362220643d226d3139322e36372c34332e3031632d312e32342c312e31382d33610e808201527f2e32322c312e31342d342e34312d2e312d312e31362d312e32322d312e31322d610ea08201527f332e322e30392d342e33372c312e32342d312e322c332e31392d312e31372c34610ec08201527f2e342e30382c312e322c312e32342c312e31372c332e32312d2e30382c342e34610ee08201527f6d31302e35322d362e3937632e35362d2e35372e38362d312e33342e38312d32610f008201527f2e3134762d2e3032632d2e31332d322e34332d332e30382d332e35362d342e38610f208201527f312d312e38346c2d322e37392c322e3834632d2e38392e38392d322e39352c31610f408201527f2e30332d342e30312d2e30336c2d362e36372d362e3735632d2e35332d2e3535610f608201527f2d312e32362d2e38362d322e30322d2e38362d322e35312c302d332e37362c33610f808201527f2e30332d312e39392c342e38316c322e38312c322e373163312e30322c312e31610fa08201527f312e39312c332e30372c302c332e39386c2d362e37352c362e3737632d2e3532610fc08201527f2e35322d2e38322c312e32322d2e38322c312e3936762e3036632d2e30332c32610fe08201527f2e35332c332e30322c332e38312c342e38312c322e30336c322e38312d322e386110008201527f32632e39382d2e39382c332e30312d2e39392c342e30332e30346c362e36342c6110208201527f362e3638632e35352e35352c312e332e38352c322e30382e3832683063322e346110408201527f372d2e30372c332e36352d332e30362c312e39312d342e38316c2d322e36382d6110608201527f322e3731632d2e39392d2e39392d312e30372d322e39312c302d332e39386c366110808201527f2e36352d362e37355a222f3e2020202020203c2f673e2020202020203c673e206110a08201527f202020202020203c706f6c79676f6e20636c6173733d22636c732d362220706f6110c082018190527f696e74733d223231332e33392033302e3532203231332e33392033382e3835206110e08301527f3231302e36372033382e3835203231302e36372032362e3038203231332e34376111008301527f2032362e3038203231392e33392033342e31203231392e33392032362e3038206111208301527f3232322e31312032362e3038203232322e31312033382e3835203231392e34386111408301527f2033382e3835203231332e33392033302e3532222f3e20202020202020203c706111608301527f61746820636c6173733d22636c732d362220643d226d3232362e34392c33332e6111808301527f333568342e3536632d2e30362d2e38382d2e36372d322e30352d322e32382d326111a08301527f2e30352d312e35312c302d322e31362c312e31332d322e32382c322e30356d326111c08301527f2e32382d332e393863322e37362c302c342e36342c322e30372c342e36342c356111e08301527f2e3039762e3534682d362e3838632e31352c312e31372c312e30392c322e31346112008301527f2c322e36362c322e31342e38362c302c312e38382d2e33342c322e34372d2e396112208301527f326c312e30372c312e3537632d2e39322e38342d322e33372c312e32382d332e6112408301527f38312c312e32382d322e38322c302d342e39342d312e392d342e39342d342e386112608301527f362c302d322e36382c312e39372d342e38352c342e37392d342e3835222f3e206112808301526112a08201527f696e74733d223233382e39352033352e3733203233362e38322033382e3835206112c08201527f3233342e31322033382e3835203233372e342033342e31203233342e333120326112e08201527f392e36203233372e30332032392e36203233382e39352033322e3435203234306113008201527f2e38352032392e36203234332e35372032392e36203234302e34362033342e316113208201527f203234332e37382033382e3835203234312e30362033382e3835203233382e396113408201527f352033352e3733222f3e20202020202020203c7061746820636c6173733d22636113608201527f6c732d362220643d226d3235312e32332c33372e3638632d2e36332e37312d316113808201527f2e37342c312e342d332e32362c312e342d322e30332c302d322e39392d312e316113a08201527f312d322e39392d322e3931762d362e353768322e343376352e363163302c312e6113c08201527f32382e36372c312e372c312e372c312e372e39342c302c312e36392d2e35322c6113e08201527f322e31312d312e3035762d362e323668322e343376392e3235682d322e3433766114008201527f2d312e31375a222f3e20202020202020203c7061746820636c6173733d22636c6114208201527f732d362220643d226d3235362e33322c33352e3934632e36372e36332c322e306114408201527f352c312e32362c332e322c312e32362c312e30352c302c312e35352d2e34322c6114608201527f312e35352d312c302d2e36332d2e38342d2e382d312e38362d312d312e35392d6114808201527f2e33312d332e36342d2e37312d332e36342d322e39332c302d312e35352c312e6114a08201527f33362d322e39312c332e37392d322e39312c312e35372c302c322e38322e35346114c08201527f2c332e37342c312e32366c2d2e39382c312e3637632d2e35362d2e35392d312e6114e08201527f36312d312e30372d322e37342d312e30372d2e38382c302d312e34362e342d316115008201527f2e34362e3932732e37332e36392c312e37362e3963312e35392e33312c332e376115208201527f322e37352c332e37322c332e30362c302c312e36392d312e34342c322e39372d6115408201527f342c322e39372d312e36312c302d332e31362d2e35342d342e31342d312e34346115608201527f6c312e30352d312e375a222f3e2020202020203c2f673e2020202020203c70616115808201527f746820636c6173733d22636c732d362220643d226d3233322e32382c35342e366115a08201527f632d2e36332e37312d312e37342c312e342d332e32362c312e342d322e30332c6115c08201527f302d322e39392d312e31312d322e39392d322e3931762d362e353768322e34336115e08201527f76352e363163302c312e32382e36372c312e372c312e372c312e372e39342c306116008201527f2c312e36392d2e35322c322e31312d312e3035762d362e323668322e343376396116208201527f2e3235682d322e3433762d312e31375a222f3e2020202020203c7061746820636116408201527f6c6173733d22636c732d362220643d226d3233372e37362c35332e3437762d346116608201527f2e3833682d312e3533762d322e313368312e3533762d322e353368322e3435766116808201527f322e353368312e383876322e3133682d312e383876342e313863302c2e35372e6116a08201527f33312c312e30322e38342c312e30322e33362c302c2e37312d2e31332e38342d6116c08201527f2e32376c2e35322c312e3834632d2e33362e33332d312e30322e35392d322e306116e08201527f332e35392d312e372c302d322e36322d2e38382d322e36322d322e3533222f3e6117008201527f2020202020203c7061746820636c6173733d22636c732d362220643d226d32356117208201527f302c35342e36632d2e36332e37312d312e37342c312e342d332e32362c312e346117408201527f2d322e30332c302d322e39392d312e31312d322e39392d322e3931762d362e356117608201527f3768322e343376352e363163302c312e32382e36372c312e372c312e372c312e6117808201527f372e39342c302c312e36392d2e35322c322e31312d312e3035762d362e3236686117a08201527f322e343376392e3235682d322e3433762d312e31375a222f3e2020202020203c6117c08201527f7061746820636c6173733d22636c732d362220643d226d3236302e342c35322e6117e08201527f34632d2e342d2e35342d312e31372d2e382d312e39352d2e382d2e39362c302d6118008201527f312e37342e352d312e37342c312e34732e37382c312e33362c312e37342c312e6118208201527f3336632e37392c302c312e35352d2e32372c312e39352d2e38762d312e31355a6118408201527f6d302c322e3431632d2e36332e37352d312e37322c312e31392d322e39332c316118608201527f2e31392d312e34382c302d332e32322d312d332e32322d332e303673312e37346118808201527f2d322e39352c332e32322d322e393563312e32332c302c322e33322e33382c326118a08201527f2e39332c312e3133762d312e323863302d2e39342d2e382d312e35352d322e306118c08201527f332d312e35352d312c302d312e39322e33362d322e372c312e30396c2d2e39326118e08201527f2d312e363363312e31332d312c322e35392d312e34362c342e30342d312e34366119008201527f2c322e31312c302c342e30342e38342c342e30342c332e3576352e3938682d326119208201527f2e3433762d2e39365a222f3e20203c2f673e203c7465787420636c6173733d226119408201527f636c732d372220783d2237252220793d22323525223e3c747370616e3e436f766119608201527f657220496e666f3c2f747370616e3e3c2f746578743e203c7465787420636c616119808201527f73733d22636c732d382220783d2237252220793d22333525223e3c747370616e6119a08201527f3e50726f647563743a3c2f747370616e3e3c2f746578743e203c7465787420636119c08201527f6c6173733d22636c732d382220783d2237252220793d22343025223e3c7473706119e08201527f616e3e416d6f756e743a3c2f747370616e3e3c2f746578743e203c7465787420611a008201527f636c6173733d22636c732d382220783d2237252220793d22343525223e3c7473611a208201527f70616e3e45787069727920446174653a203c2f747370616e3e3c2f746578743e611a408201527f203c7465787420636c6173733d22636c732d382220783d2237252220793d2235611a608201527f3025223e3c747370616e3e436f7665722049443a3c2f747370616e3e3c2f7465611a808201527f78743e202020203c7465787420636c6173733d22636c732d392220783d223933611aa08201527f252220793d223335252220746578742d616e63686f723d22656e64223e000000611ac08201526000611415611add830184611691565b60008251613cf88184602087016113b2565b9190910192915050565b8051801515811461173757600080fd5b600060608284031215613d2457600080fd5b613d2c6114e9565b8251613d37816116d6565b8152613d4560208401613d02565b60208201526117a660408401613d02565b683d913730b6b2911d1160b91b81528351600090613d7b8160098501602089016113b2565b61088b60f21b60099184019182018190526e113232b9b1b934b83a34b7b7111d1160891b600b8301528551613db781601a850160208a016113b2565b601a920191820152691134b6b0b3b2911d101160b11b601c8201527f646174613a696d6167652f7376672b786d6c3b6261736536342c00000000000060268201528351613e0b8160408401602088016113b2565b61227d60f01b6040929091019182015260420195945050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000815260008251613e5f81601d8501602087016113b2565b91909101601d0192915050565b600060208284031215613e7e57600080fd5b6114158261173c565b600060018201613e9957613e99611829565b5060010190565b634e487b7160e01b600052601260045260246000fd5b600082613ec557613ec5613ea0565b500490565b600082613ed957613ed9613ea0565b500690565b808201808211156101a8576101a8611829565b634e487b7160e01b600052603260045260246000fd5b80820281158282048414176101a8576101a8611829565b60008251613f308184602087016113b2565b6202e30360ec1b920191825250600301919050565b600181815b80851115613f80578160001904821115613f6657613f66611829565b80851615613f7357918102915b93841c9390800290613f4a565b509250929050565b600082613f97575060016101a8565b81613fa4575060006101a8565b8160018114613fba5760028114613fc457613fe0565b60019150506101a8565b60ff841115613fd557613fd5611829565b50506001821b6101a8565b5060208310610133831016604e8410600b8410161715614003575081810a6101a8565b61400d8383613f45565b806000190482111561402157614021611829565b029392505050565b60006114158383613f88565b600082516140478184602087016113b2565b601760f91b920191825250600101919050565b6000825161406c8184602087016113b2565b61030360f41b920191825250600201919050565b600083516140928184602088016113b2565b8351908301906140a68183602088016113b2565b01949350505050565b80820182811260008312801582168215821617156140cf576140cf611829565b505092915050565b80820260008212600160ff1b841416156140f3576140f3611829565b81810583148215176101a8576101a8611829565b60008261411657614116613ea0565b600160ff1b82146000198414161561413057614130611829565b500590565b81810360008312801583831316838312821617156119045761190461182956fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f5468697320636f766572204e46542068617320616c72656164792065787069726564a26469706673582212200603e98f01578afda4e545465176ef4053ec90efd2e2998292b81f94153a21c264736f6c6343000812003300000000000000000000000001bfd82675dbcc7762c84019ca518e701c0cd07e
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061007d5760003560e01c80636f9759811161005b5780636f975981146100df578063c87b56dd146100f2578063ee97f7f314610105578063f6de23601461014457600080fd5b806322a3560a146100825780632409145e146100ab5780634e6d052d146100cc575b600080fd5b610095610090366004611399565b610165565b6040516100a29190611402565b60405180910390f35b6100be6100b9366004611399565b6101ae565b6040516100a292919061141c565b6100956100da3660046115bb565b6106b8565b6100956100ed366004611399565b610754565b610095610100366004611399565b6108ef565b61012c7f00000000000000000000000001bfd82675dbcc7762c84019ca518e701c0cd07e81565b6040516001600160a01b0390911681526020016100a2565b610157610152366004611399565b6109d0565b6040519081526020016100a2565b6060600a82101561019f5761017982610b53565b60405160200161018991906116ad565b6040516020818303038152906040529050919050565b6101a882610b53565b92915050565b60606101e96040518060c001604052806060815260200160608152602001606081526020016000815260200160008152602001600081525090565b6040516227050b60e31b815261434f60f01b60048201526000907f00000000000000000000000001bfd82675dbcc7762c84019ca518e701c0cd07e6001600160a01b031690630138285890602401602060405180830381865afa158015610254573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061027891906116ee565b905083816001600160a01b031663404730f46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102dd919061170b565b101561036b5750506040805160e081018252600060c082018181528252825160208181018552828252808401919091528351808201855282815283850152606083018290526080830182905260a08301919091528251808401909352601783527f54686973204e465420646f6573206e6f742065786973740000000000000000009083015290939092509050565b60405163bce2a88360e01b8152600481018590526000906001600160a01b0383169063bce2a88390602401606060405180830381865afa1580156103b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d79190611764565b80516040516372ca814160e11b815262ffffff90911660048201529091506000906001600160a01b0384169063e595028290602401600060405180830381865afa158015610429573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261045191908101906117b2565b90506000836001600160a01b031663ccfa4b79886001876001600160a01b031663638233088c6040518263ffffffff1660e01b815260040161049591815260200190565b602060405180830381865afa1580156104b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104d6919061170b565b6104e0919061183f565b6040516001600160e01b031960e085901b1681526004810192909252602482015260440160c060405180830381865afa158015610521573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105459190611866565b90506060428260400151836020015161055e91906118e7565b63ffffffff1611610585576040518060600160405280602281526020016141966022913990505b606060008060006105ae866040015187602001516105a391906118e7565b63ffffffff16610c54565b9250925092506105bd82610c8d565b6105c682610165565b6105cf85610b53565b6040516020016105e19392919061190b565b60405160208183030381529060405293505050508361061c84600001516001600160601b0316610617886020015160ff166109d0565b610e9f565b61062c876020015160ff16610754565b8385604051602001610642959493929190611965565b60405160208183030381529060405297506040518060c00160405280858152602001610674876020015160ff16610754565b815260200182815260200184600001516001600160601b031681526020018a81526020016106a8876020015160ff166109d0565b8152509650505050505050915091565b6060600082600001516106d384606001518560a00151610e9f565b846020015185604001516106ea8760800151610b53565b6040516020016106fe959493929190611a6b565b6040516020818303038152906040529050806040516020016107209190611c5e565b60408051601f198184030181529082905261073d91602001613ce6565b604051602081830303815290604052915050919050565b60608160000361077d57505060408051808201909152600381526208aa8960eb1b602082015290565b6040516227050b60e31b815261503160f01b60048201526000907f00000000000000000000000001bfd82675dbcc7762c84019ca518e701c0cd07e6001600160a01b031690630138285890602401602060405180830381865afa1580156107e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080c91906116ee565b604051631d591eb760e31b8152600481018590529091506000906001600160a01b0383169063eac8f5b890602401606060405180830381865afa158015610857573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061087b9190613d12565b905080600001516001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa1580156108bf573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108e791908101906117b2565b949350505050565b60606000806108fd846101ae565b91509150600061091461090f836106b8565b6110d2565b90506109a7336001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa158015610957573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261097f91908101906117b2565b848360405160200161099393929190613d56565b6040516020818303038152906040526110d2565b6040516020016109b79190613e27565b6040516020818303038152906040529350505050919050565b6000816000036109e257506012919050565b6040516227050b60e31b815261503160f01b60048201526000907f00000000000000000000000001bfd82675dbcc7762c84019ca518e701c0cd07e6001600160a01b031690630138285890602401602060405180830381865afa158015610a4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a7191906116ee565b604051631d591eb760e31b8152600481018590529091506000906001600160a01b0383169063eac8f5b890602401606060405180830381865afa158015610abc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ae09190613d12565b905080600001516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b489190613e6c565b60ff16949350505050565b606081600003610b7a5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ba45780610b8e81613e87565b9150610b9d9050600a83613eb6565b9150610b7e565b60008167ffffffffffffffff811115610bbf57610bbf6114aa565b6040519080825280601f01601f191660200182016040528015610be9576020820181803683370190505b5090505b84156108e757610bfe60018361183f565b9150610c0b600a86613eca565b610c16906030613ede565b60f81b818381518110610c2b57610c2b613ef1565b60200101906001600160f81b031916908160001a905350610c4d600a86613eb6565b9450610bed565b60008080610c80610c66603c80613f07565b610c71906018613f07565b610c7b9086613eb6565b611225565b9196909550909350915050565b606081600103610cb65750506040805180820190915260038152622530b760e91b602082015290565b81600203610cdd5750506040805180820190915260038152622332b160e91b602082015290565b81600303610d0457505060408051808201909152600381526226b0b960e91b602082015290565b81600403610d2b57505060408051808201909152600381526220b83960e91b602082015290565b81600503610d525750506040805180820190915260038152624d617960e81b602082015290565b81600603610d79575050604080518082019091526003815262253ab760e91b602082015290565b81600703610da0575050604080518082019091526003815262129d5b60ea1b602082015290565b81600803610dc757505060408051808201909152600381526241756760e81b602082015290565b81600903610dee57505060408051808201909152600381526205365760ec1b602082015290565b81600a03610e1557505060408051808201909152600381526213d8dd60ea1b602082015290565b81600b03610e3c5750506040805180820190915260038152622737bb60e91b602082015290565b81600c03610e6357505060408051808201909152600381526244656360e81b602082015290565b60405162461bcd60e51b815260206004820152600d60248201526c092dcecc2d8d2c840dadedce8d609b1b604482015260640160405180910390fd5b606081600003610ed857610eb283610b53565b604051602001610ec29190613f1e565b60405160208183030381529060405290506101a8565b6000610ee583600a614029565b90506000610ef38286613eb6565b9050610efe81610b53565b604051602001610f0e9190614035565b60408051601f1981840301815291905292506000610f2c8387613eca565b90506000610f3982610b53565b805190915081908790610f4d906001613ede565b1015610f7f5785604051602001610f64919061405a565b604051602081830303815290604052955050505050506101a8565b610f8a600a86613eb6565b831015610ff15780600081518110610fa457610fa4613ef1565b01602090810151604051600360fc1b928101929092526001600160f81b03191660218201526022015b60405160208183030381529060405291508582604051602001610f64929190614080565b805160010361103c578060008151811061100d5761100d613ef1565b016020908101516040516001600160f81b031990911691810191909152600360fc1b6021820152602201610fcd565b8060008151811061104f5761104f613ef1565b602001015160f81c60f81b8160018151811061106d5761106d613ef1565b60209101810151604080516001600160f81b0319948516938101939093529216602182015281516002818303018152602282019092529092506110b69087908490604201614080565b6040516020818303038152906040529550505050505092915050565b606081516000036110f157505060408051602081019091526000815290565b600060405180606001604052806040815260200161415660409139905060006003845160026111209190613ede565b61112a9190613eb6565b611135906004613f07565b67ffffffffffffffff81111561114d5761114d6114aa565b6040519080825280601f01601f191660200182016040528015611177576020820181803683370190505b509050600182016020820185865187015b808210156111e3576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250611188565b50506003865106600181146111ff57600281146112125761121a565b603d6001830353603d600283035361121a565b603d60018303535b509195945050505050565b60008080838162253d8c61123c8362010bd96140af565b61124691906140af565b9050600062023ab16112598360046140d7565b6112639190614107565b905060046112748262023ab16140d7565b61127f9060036140af565b6112899190614107565b6112939083614135565b9150600062164b096112a68460016140af565b6112b290610fa06140d7565b6112bc9190614107565b905060046112cc826105b56140d7565b6112d69190614107565b6112e09084614135565b6112eb90601f6140af565b9250600061098f6112fd8560506140d7565b6113079190614107565b9050600060506113198361098f6140d7565b6113239190614107565b61132d9086614135565b905061133a600b83614107565b945061134785600c6140d7565b6113528360026140af565b61135c9190614135565b9150848361136b603187614135565b6113769060646140d7565b61138091906140af565b61138a91906140af565b9a919950975095505050505050565b6000602082840312156113ab57600080fd5b5035919050565b60005b838110156113cd5781810151838201526020016113b5565b50506000910152565b600081518084526113ee8160208601602086016113b2565b601f01601f19169290920160200192915050565b60208152600061141560208301846113d6565b9392505050565b60408152600061142f60408301856113d6565b8281036020840152835160c0825261144a60c08301826113d6565b90506020850151828203602084015261146382826113d6565b9150506040850151828203604084015261147d82826113d6565b915050606085015160608301526080850151608083015260a085015160a083015280925050509392505050565b634e487b7160e01b600052604160045260246000fd5b60405160c0810167ffffffffffffffff811182821017156114e3576114e36114aa565b60405290565b6040516060810167ffffffffffffffff811182821017156114e3576114e36114aa565b604051601f8201601f1916810167ffffffffffffffff81118282101715611535576115356114aa565b604052919050565b600067ffffffffffffffff821115611557576115576114aa565b50601f01601f191660200190565b600082601f83011261157657600080fd5b81356115896115848261153d565b61150c565b81815284602083860101111561159e57600080fd5b816020850160208301376000918101602001919091529392505050565b6000602082840312156115cd57600080fd5b813567ffffffffffffffff808211156115e557600080fd5b9083019060c082860312156115f957600080fd5b6116016114c0565b82358281111561161057600080fd5b61161c87828601611565565b82525060208301358281111561163157600080fd5b61163d87828601611565565b60208301525060408301358281111561165557600080fd5b61166187828601611565565b604083015250606083013560608201526080830135608082015260a083013560a082015280935050505092915050565b600081516116a38185602086016113b2565b9290920192915050565b600360fc1b8152600082516116c98160018501602087016113b2565b9190910160010192915050565b6001600160a01b03811681146116eb57600080fd5b50565b60006020828403121561170057600080fd5b8151611415816116d6565b60006020828403121561171d57600080fd5b5051919050565b805162ffffff8116811461173757600080fd5b919050565b805160ff8116811461173757600080fd5b80516001600160601b038116811461173757600080fd5b60006060828403121561177657600080fd5b61177e6114e9565b61178783611724565b81526117956020840161173c565b60208201526117a66040840161174d565b60408201529392505050565b6000602082840312156117c457600080fd5b815167ffffffffffffffff8111156117db57600080fd5b8201601f810184136117ec57600080fd5b80516117fa6115848261153d565b81815285602083850101111561180f57600080fd5b6118208260208301602086016113b2565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b818103818111156101a8576101a8611829565b805163ffffffff8116811461173757600080fd5b600060c0828403121561187857600080fd5b6118806114c0565b6118898361174d565b815261189760208401611852565b60208201526118a860408401611852565b60408201526118b960608401611852565b60608201526118ca60808401611724565b60808201526118db60a08401611724565b60a08201529392505050565b63ffffffff81811683821601908082111561190457611904611829565b5092915050565b6000845161191d8184602089016113b2565b8083019050600160fd1b808252855161193d816001850160208a016113b2565b600192019182015283516119588160028401602088016113b2565b0160020195945050505050565b7f54686973204e465420726570726573656e7473206120636f76657220707572638152600060206e03430b9b29036b0b232903337b91d1608d1b8184015287516119b581602f8601848c016113b2565b720102e3720b6b7bab73a1021b7bb32b932b21d1606d1b602f9185019182015287516119e78160428401858c016113b2565b600160fd1b604292909101918201528651611a088160438401858b016113b2565b6f0102e3722bc3834b93c902230ba329d160851b604392909101918201528551611a388160538401858a016113b2565b62102e3760e91b605392909101918201528451611a5b81605684018589016113b2565b0160560198975050505050505050565b6000661e3a39b830b71f60c91b8083528751611a8e816007860160208c016113b2565b7f3c2f747370616e3e3c2f746578743e20203c7465787420636c6173733d22636c6007918501918201527f732d392220783d223933252220793d223430252220746578742d616e63686f726027820152661e9132b732111f60c91b6047820152604e810191909152865190611b0a826055830160208b016113b2565b818101915050600160fd1b60558201528551611b2d816056840160208a016113b2565b611c51611c28611c22611bd3611bb8611bb2611b636056888a01016e1e17ba39b830b71f1e17ba32bc3a1f60891b8152600f0190565b7f3c7465787420636c6173733d22636c732d392220783d223933252220793d223481527f35252220746578742d616e63686f723d22656e64223e3c747370616e3e0000006020820152603d0190565b8b611691565b6e1e17ba39b830b71f1e17ba32bc3a1f60891b8152600f0190565b7f3c7465787420636c6173733d22636c732d392220783d223933252220793d223581527f30252220746578742d616e63686f723d22656e64223e3c747370616e3e0000006020820152603d0190565b87611691565b7f3c2f747370616e3e3c2f746578743e20203c2f673e3c2f7376673e00000000008152601b0190565b9998505050505050505050565b7f3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323081527f30302f7376672220786d6c6e733a786c696e6b3d22687474703a2f2f7777772e60208201527f77332e6f72672f313939392f786c696e6b222076696577426f783d223020302060408201527f32393020353030223e20203c646566733e202020203c7374796c653e2020202060608201527f20202e636c732d31207b2066696c6c3a206e6f6e653b207d2020202020202e6360808201527f6c732d33207b20636c69702d706174683a2075726c2823637031293b207d202060a08201527f202020202e636c732d34207b206f7061636974793a202e30343b207d2020202060c08201527f20202e636c732d35207b2066696c6c3a20233035353033373b207d202020202060e08201527f202e636c732d362c202e636c732d372c202e636c732d382c202e636c732d39206101008201527f7b2066696c6c3a20236666663b207d2020202020202e636c732d37207b20666f6101208201527f6e742d73697a653a20313870783b207d2020202020202e636c732d372c202e636101408201527f6c732d382c202e636c732d39207b20666f6e742d66616d696c793a20417269616101608201527f6c4d542c20417269616c2c2073616e732d73657269663b207d2020202020202e6101808201527f636c732d39207b20636c69702d706174683a2075726c2823637032293b207d206101a08201527f20202020202e636c732d382c202e636c732d39207b20666f6e742d73697a653a6101c08201527f20313370783b207d202020203c2f7374796c653e202020203c636c69705061746101e08201527f682069643d22637031223e2020202020203c7265637420636c6173733d22636c6102008201527f732d31222077696474683d2232393022206865696768743d22353030222072786102208201527f3d2233322e3734222072793d2233322e3734222f3e202020203c2f636c6970506102408201527f6174683e202020203c636c6970506174682069643d22637032223e20202020206102608201527f203c7265637420636c6173733d22636c732d312220783d222d3338322e3138226102808201527f20793d222d3930222077696474683d223936382e383522206865696768743d226102a08201527f393731222f3e202020203c2f636c6970506174683e20203c2f646566733e20206102c08201527f3c673e202020203c7265637420636c6173733d22636c732d352220793d2230226102e08201527f2077696474683d2232393022206865696768743d22353030222072783d2233326103008201527f2e3734222072793d2233322e3734222f3e202020203c673e2020202020203c706103208201527f61746820636c6173733d22636c732d362220643d226d3133372e36352c3334346103408201527f2e323963352e39372d352e37362c362e31342d31352e32362e33382d32312e326103608201527f33732d31352e32362d362e31342d32312e32332d2e33382d362e31342c31352e6103808201527f32362d2e33382c32312e323363352e37362c352e39372c31352e32362c362e316103a08201527f342c32312e32332e33385a222f3e2020202020203c7061746820636c6173733d6103c082018190527f22636c732d362220643d226d35352e38352c3338322e383463352e39372d352e6103e08301527f37362c362e31342d31352e32362e33382d32312e3233732d31352e32362d362e6104008301527f31342d32312e32332d2e3338632d352e39372c352e37362d362e31342c31352e6104208301527f32362d2e33382c32312e32332c352e37362c352e39372c31352e32362c362e316104408301526104608201527f22636c732d362220643d226d39352e322c3434332e3535632d352e37382d352e6104808201527f39352d31352e32382d362e30392d32312e32332d2e33312d352e39322c352e376104a08201527f352d362e30392c31352e322d2e33382c32312e3136683063352e372c362e30326104c08201527f2c31352e322c362e32382c32312e32332e35382c362e30322d352e372c362e326104e08201527f382d31352e322e35382d32312e32332d2e30362d2e30372d2e31332d2e31342d6105008201527f2e322d2e325a222f3e2020202020203c7061746820636c6173733d22636c732d6105208201527f362220643d226d3137362e33382c3430342e3339632d352e37362d352e39372d6105408201527f31352e32362d362e31342d32312e32332d2e33382d352e39372c352e37362d366105608201527f2e31342c31352e32362d2e33382c32312e32332c352e37362c352e39372c31356105808201527f2e32362c362e31342c32312e32332e33382c352e39372d352e37362c362e31346105a08201527f2d31352e32362e33382d32312e32335a222f3e2020202020203c7061746820636105c08201527f6c6173733d22636c732d362220643d226d3137302e322c3336392e343163322e6105e08201527f38352d322e38372c342e33352d362e38322c342e31332d31302e3836762d2e316106008201527f31632d2e36382d31322e33342d31352e36352d31382e30372d32342e33392d396106208201527f2e33336c2d31342e31352c31342e34632d342e35332c342e35332d31352c352e6106408201527f32322d32302e33372d2e31366c2d33332e38342d33342e3234632d322e36392d6106608201527f322e37382d362e342d342e33352d31302e32372d342e33352d31322e37342c306106808201527f2d31392e31312c31352e342d31302e312c32342e34316c31342e32372c31332e6106a08201527f373763352e31392c352e36352c342e36322c31352e362c302c32302e32326c2d6106c08201527f33342e32382c33342e3335632d322e36342c322e36342d342e31342c362e32316106e08201527f2d342e31392c392e3934762e3332632d2e31352c31322e38322c31352e33342c6107008201527f31392e33342c32342e342c31302e32386c31342e32342d31342e333163342e396107208201527f362d342e39362c31352e32372d352e30312c32302e34362e31386c33332e372c6107408201527f33332e3963322e37392c322e37392c362e362c342e332c31302e35332c342e316107608201527f38682e30356331322e35332d2e33372c31382e35352d31352e35342c392e36396107808201527f2d32342e346c2d31332e36312d31332e3735632d352e30352d352e30352d352e6107a08201527f34332d31342e37392d2e30332d32302e31396c33332e37372d33342e32355a6d6107c08201527f2d35332e34322c33352e3338632d362e32372c362e30352d31362e32362c352e6107e08201527f38372d32322e33322d2e342d362e30352d362e32372d352e38372d31362e32366108008201527f2e342d32322e33322c362e32372d362e30352c31362e32362d352e38372c32326108208201527f2e33322e342c362e30352c362e32372c352e38372c31362e32362d2e342c32326108408201527f2e33325a222f3e202020203c2f673e202020203c7265637420636c6173733d226108608201527f636c732d31222077696474683d2232393022206865696768743d2235303022206108808201527f72783d2233322e3734222072793d2233322e3734222f3e202020203c6720636c6108a08201527f6173733d22636c732d34223e2020202020203c6720636c6173733d22636c732d6108c08201527f33223e20202020202020203c6720636c6173733d22636c732d39223e202020206108e08201527f2020202020203c7061746820636c6173733d22636c732d362220643d226d31366109008201527f362e32312c3139392e35374c302c33312e3431763436382e3539683237392e346109208201527f3263322e30362d382e33382c352e32342d31362e34372c392e35382d32332e396109408201527f33563230372e3736632d33322e32392c32322e35342d39312e31372c32332e346109608201527f342d3132322e37392d382e31385a6d382e37382c3236372e3235632d34302e346109808201527f352c33392e30332d3130342e38382c33372e38382d3134332e39322d322e35376109a08201527f2d33392e30332d34302e34352d33372e38382d3130342e38382c322e35372d316109c08201527f34332e39322c34302e34352d33392e30332c3130342e38382d33372e38382c316109e08201527f34332e39322c322e35372c33392e30332c34302e34352c33372e38382c313034610a008201527f2e38382d322e35372c3134332e39325a222f3e202020202020202020203c7061610a208201527f746820636c6173733d22636c732d362220643d226d3239302c30682d3134342e610a408201527f3234632d312e39322c32362e34382c362e39392c35332e36342c32362e38382c610a608201527f37342e32362c33312e33322c33322e34362c37392e38352c33382e33322c3131610a808201527f372e33362c31372e303756305a222f3e20202020202020203c2f673e20202020610aa08201527f20203c2f673e202020203c2f673e202020203c673e2020202020203c706f6c79610ac08201527f676f6e20636c6173733d22636c732d362220706f696e74733d223232312e3136610ae08201527f2034362e3639203231372e37362035352e3737203231362e36342035352e3737610b008201527f203231332e32342034362e3639203231332e32342035352e3737203231302e36610b208201527f372035352e3737203231302e36372034332e3238203231342e32372034332e32610b408201527f38203231372e322035302e3634203232302e31332034332e3238203232332e37610b608201527f352034332e3238203232332e37352035352e3737203232312e31362035352e37610b808201527f37203232312e31362034362e3639222f3e2020202020203c7265637420636c61610ba08201527f73733d22636c732d362220783d223236352e32352220793d2234322e39392220610bc08201527f77696474683d22322e343322206865696768743d2231322e3738222f3e202020610be08201527f2020203c673e20202020202020203c7061746820636c6173733d22636c732d36610c008201527f2220643d226d3230342e33342c34372e313163312e31382d312e31332c312e32610c208201527f322d332c2e30382d342e31382d312e31352d312e31382d332d312e32322d342e610c408201527f31382d2e30372d312e31362c312e31322d312e31392c332d2e30392c342e3136610c608201527f2c312e31332c312e31382c332e30312c312e32322c342e31392e31222f3e2020610c808201527f2020202020203c7061746820636c6173733d22636c732d362220643d226d3138610ca08201527f342e31362c35342e373563312e31332c312e31382c332c312e32322c342e3138610cc08201527f2e30382c312e31382d312e31352c312e32322d332c2e30372d342e31382d312e610ce08201527f31322d312e31362d332d312e31392d342e31362d2e30392d312e31382c312e31610d008201527f332d312e32322c332e30312d2e312c342e3139222f3e20202020202020203c70610d208201527f61746820636c6173733d22636c732d362220643d226d3137362e35362c33342e610d408201527f3433632d312e31382c312e31332d312e32322c332d2e30382c342e31382c312e610d608201527f31352c312e31382c332c312e32322c342e31382e30372c312e31362d312e3132610d808201527f2c312e31392d332c2e30392d342e31362d312e31332d312e31382d332e30312d610da08201527f312e32322d342e31392d2e31222f3e20202020202020203c7061746820636c61610dc08201527f73733d22636c732d362220643d226d3139362e38362c32362e3931632d312e31610de08201527f332d312e31382d332d312e32322d342e31382d2e30382d312e31382c312e3135610e008201527f2d312e32322c332d2e30372c342e31382c312e31322c312e31362c332c312e31610e208201527f392c342e31362e30392c312e31382d312e31332c312e32322d332e30312e312d610e408201527f342e3139222f3e20202020202020203c7061746820636c6173733d22636c732d610e608201527f362220643d226d3139322e36372c34332e3031632d312e32342c312e31382d33610e808201527f2e32322c312e31342d342e34312d2e312d312e31362d312e32322d312e31322d610ea08201527f332e322e30392d342e33372c312e32342d312e322c332e31392d312e31372c34610ec08201527f2e342e30382c312e322c312e32342c312e31372c332e32312d2e30382c342e34610ee08201527f6d31302e35322d362e3937632e35362d2e35372e38362d312e33342e38312d32610f008201527f2e3134762d2e3032632d2e31332d322e34332d332e30382d332e35362d342e38610f208201527f312d312e38346c2d322e37392c322e3834632d2e38392e38392d322e39352c31610f408201527f2e30332d342e30312d2e30336c2d362e36372d362e3735632d2e35332d2e3535610f608201527f2d312e32362d2e38362d322e30322d2e38362d322e35312c302d332e37362c33610f808201527f2e30332d312e39392c342e38316c322e38312c322e373163312e30322c312e31610fa08201527f312e39312c332e30372c302c332e39386c2d362e37352c362e3737632d2e3532610fc08201527f2e35322d2e38322c312e32322d2e38322c312e3936762e3036632d2e30332c32610fe08201527f2e35332c332e30322c332e38312c342e38312c322e30336c322e38312d322e386110008201527f32632e39382d2e39382c332e30312d2e39392c342e30332e30346c362e36342c6110208201527f362e3638632e35352e35352c312e332e38352c322e30382e3832683063322e346110408201527f372d2e30372c332e36352d332e30362c312e39312d342e38316c2d322e36382d6110608201527f322e3731632d2e39392d2e39392d312e30372d322e39312c302d332e39386c366110808201527f2e36352d362e37355a222f3e2020202020203c2f673e2020202020203c673e206110a08201527f202020202020203c706f6c79676f6e20636c6173733d22636c732d362220706f6110c082018190527f696e74733d223231332e33392033302e3532203231332e33392033382e3835206110e08301527f3231302e36372033382e3835203231302e36372032362e3038203231332e34376111008301527f2032362e3038203231392e33392033342e31203231392e33392032362e3038206111208301527f3232322e31312032362e3038203232322e31312033382e3835203231392e34386111408301527f2033382e3835203231332e33392033302e3532222f3e20202020202020203c706111608301527f61746820636c6173733d22636c732d362220643d226d3232362e34392c33332e6111808301527f333568342e3536632d2e30362d2e38382d2e36372d322e30352d322e32382d326111a08301527f2e30352d312e35312c302d322e31362c312e31332d322e32382c322e30356d326111c08301527f2e32382d332e393863322e37362c302c342e36342c322e30372c342e36342c356111e08301527f2e3039762e3534682d362e3838632e31352c312e31372c312e30392c322e31346112008301527f2c322e36362c322e31342e38362c302c312e38382d2e33342c322e34372d2e396112208301527f326c312e30372c312e3537632d2e39322e38342d322e33372c312e32382d332e6112408301527f38312c312e32382d322e38322c302d342e39342d312e392d342e39342d342e386112608301527f362c302d322e36382c312e39372d342e38352c342e37392d342e3835222f3e206112808301526112a08201527f696e74733d223233382e39352033352e3733203233362e38322033382e3835206112c08201527f3233342e31322033382e3835203233372e342033342e31203233342e333120326112e08201527f392e36203233372e30332032392e36203233382e39352033322e3435203234306113008201527f2e38352032392e36203234332e35372032392e36203234302e34362033342e316113208201527f203234332e37382033382e3835203234312e30362033382e3835203233382e396113408201527f352033352e3733222f3e20202020202020203c7061746820636c6173733d22636113608201527f6c732d362220643d226d3235312e32332c33372e3638632d2e36332e37312d316113808201527f2e37342c312e342d332e32362c312e342d322e30332c302d322e39392d312e316113a08201527f312d322e39392d322e3931762d362e353768322e343376352e363163302c312e6113c08201527f32382e36372c312e372c312e372c312e372e39342c302c312e36392d2e35322c6113e08201527f322e31312d312e3035762d362e323668322e343376392e3235682d322e3433766114008201527f2d312e31375a222f3e20202020202020203c7061746820636c6173733d22636c6114208201527f732d362220643d226d3235362e33322c33352e3934632e36372e36332c322e306114408201527f352c312e32362c332e322c312e32362c312e30352c302c312e35352d2e34322c6114608201527f312e35352d312c302d2e36332d2e38342d2e382d312e38362d312d312e35392d6114808201527f2e33312d332e36342d2e37312d332e36342d322e39332c302d312e35352c312e6114a08201527f33362d322e39312c332e37392d322e39312c312e35372c302c322e38322e35346114c08201527f2c332e37342c312e32366c2d2e39382c312e3637632d2e35362d2e35392d312e6114e08201527f36312d312e30372d322e37342d312e30372d2e38382c302d312e34362e342d316115008201527f2e34362e3932732e37332e36392c312e37362e3963312e35392e33312c332e376115208201527f322e37352c332e37322c332e30362c302c312e36392d312e34342c322e39372d6115408201527f342c322e39372d312e36312c302d332e31362d2e35342d342e31342d312e34346115608201527f6c312e30352d312e375a222f3e2020202020203c2f673e2020202020203c70616115808201527f746820636c6173733d22636c732d362220643d226d3233322e32382c35342e366115a08201527f632d2e36332e37312d312e37342c312e342d332e32362c312e342d322e30332c6115c08201527f302d322e39392d312e31312d322e39392d322e3931762d362e353768322e34336115e08201527f76352e363163302c312e32382e36372c312e372c312e372c312e372e39342c306116008201527f2c312e36392d2e35322c322e31312d312e3035762d362e323668322e343376396116208201527f2e3235682d322e3433762d312e31375a222f3e2020202020203c7061746820636116408201527f6c6173733d22636c732d362220643d226d3233372e37362c35332e3437762d346116608201527f2e3833682d312e3533762d322e313368312e3533762d322e353368322e3435766116808201527f322e353368312e383876322e3133682d312e383876342e313863302c2e35372e6116a08201527f33312c312e30322e38342c312e30322e33362c302c2e37312d2e31332e38342d6116c08201527f2e32376c2e35322c312e3834632d2e33362e33332d312e30322e35392d322e306116e08201527f332e35392d312e372c302d322e36322d2e38382d322e36322d322e3533222f3e6117008201527f2020202020203c7061746820636c6173733d22636c732d362220643d226d32356117208201527f302c35342e36632d2e36332e37312d312e37342c312e342d332e32362c312e346117408201527f2d322e30332c302d322e39392d312e31312d322e39392d322e3931762d362e356117608201527f3768322e343376352e363163302c312e32382e36372c312e372c312e372c312e6117808201527f372e39342c302c312e36392d2e35322c322e31312d312e3035762d362e3236686117a08201527f322e343376392e3235682d322e3433762d312e31375a222f3e2020202020203c6117c08201527f7061746820636c6173733d22636c732d362220643d226d3236302e342c35322e6117e08201527f34632d2e342d2e35342d312e31372d2e382d312e39352d2e382d2e39362c302d6118008201527f312e37342e352d312e37342c312e34732e37382c312e33362c312e37342c312e6118208201527f3336632e37392c302c312e35352d2e32372c312e39352d2e38762d312e31355a6118408201527f6d302c322e3431632d2e36332e37352d312e37322c312e31392d322e39332c316118608201527f2e31392d312e34382c302d332e32322d312d332e32322d332e303673312e37346118808201527f2d322e39352c332e32322d322e393563312e32332c302c322e33322e33382c326118a08201527f2e39332c312e3133762d312e323863302d2e39342d2e382d312e35352d322e306118c08201527f332d312e35352d312c302d312e39322e33362d322e372c312e30396c2d2e39326118e08201527f2d312e363363312e31332d312c322e35392d312e34362c342e30342d312e34366119008201527f2c322e31312c302c342e30342e38342c342e30342c332e3576352e3938682d326119208201527f2e3433762d2e39365a222f3e20203c2f673e203c7465787420636c6173733d226119408201527f636c732d372220783d2237252220793d22323525223e3c747370616e3e436f766119608201527f657220496e666f3c2f747370616e3e3c2f746578743e203c7465787420636c616119808201527f73733d22636c732d382220783d2237252220793d22333525223e3c747370616e6119a08201527f3e50726f647563743a3c2f747370616e3e3c2f746578743e203c7465787420636119c08201527f6c6173733d22636c732d382220783d2237252220793d22343025223e3c7473706119e08201527f616e3e416d6f756e743a3c2f747370616e3e3c2f746578743e203c7465787420611a008201527f636c6173733d22636c732d382220783d2237252220793d22343525223e3c7473611a208201527f70616e3e45787069727920446174653a203c2f747370616e3e3c2f746578743e611a408201527f203c7465787420636c6173733d22636c732d382220783d2237252220793d2235611a608201527f3025223e3c747370616e3e436f7665722049443a3c2f747370616e3e3c2f7465611a808201527f78743e202020203c7465787420636c6173733d22636c732d392220783d223933611aa08201527f252220793d223335252220746578742d616e63686f723d22656e64223e000000611ac08201526000611415611add830184611691565b60008251613cf88184602087016113b2565b9190910192915050565b8051801515811461173757600080fd5b600060608284031215613d2457600080fd5b613d2c6114e9565b8251613d37816116d6565b8152613d4560208401613d02565b60208201526117a660408401613d02565b683d913730b6b2911d1160b91b81528351600090613d7b8160098501602089016113b2565b61088b60f21b60099184019182018190526e113232b9b1b934b83a34b7b7111d1160891b600b8301528551613db781601a850160208a016113b2565b601a920191820152691134b6b0b3b2911d101160b11b601c8201527f646174613a696d6167652f7376672b786d6c3b6261736536342c00000000000060268201528351613e0b8160408401602088016113b2565b61227d60f01b6040929091019182015260420195945050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000815260008251613e5f81601d8501602087016113b2565b91909101601d0192915050565b600060208284031215613e7e57600080fd5b6114158261173c565b600060018201613e9957613e99611829565b5060010190565b634e487b7160e01b600052601260045260246000fd5b600082613ec557613ec5613ea0565b500490565b600082613ed957613ed9613ea0565b500690565b808201808211156101a8576101a8611829565b634e487b7160e01b600052603260045260246000fd5b80820281158282048414176101a8576101a8611829565b60008251613f308184602087016113b2565b6202e30360ec1b920191825250600301919050565b600181815b80851115613f80578160001904821115613f6657613f66611829565b80851615613f7357918102915b93841c9390800290613f4a565b509250929050565b600082613f97575060016101a8565b81613fa4575060006101a8565b8160018114613fba5760028114613fc457613fe0565b60019150506101a8565b60ff841115613fd557613fd5611829565b50506001821b6101a8565b5060208310610133831016604e8410600b8410161715614003575081810a6101a8565b61400d8383613f45565b806000190482111561402157614021611829565b029392505050565b60006114158383613f88565b600082516140478184602087016113b2565b601760f91b920191825250600101919050565b6000825161406c8184602087016113b2565b61030360f41b920191825250600201919050565b600083516140928184602088016113b2565b8351908301906140a68183602088016113b2565b01949350505050565b80820182811260008312801582168215821617156140cf576140cf611829565b505092915050565b80820260008212600160ff1b841416156140f3576140f3611829565b81810583148215176101a8576101a8611829565b60008261411657614116613ea0565b600160ff1b82146000198414161561413057614130611829565b500590565b81810360008312801583831316838312821617156119045761190461182956fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f5468697320636f766572204e46542068617320616c72656164792065787069726564a26469706673582212200603e98f01578afda4e545465176ef4053ec90efd2e2998292b81f94153a21c264736f6c63430008120033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000001bfd82675dbcc7762c84019ca518e701c0cd07e
-----Decoded View---------------
Arg [0] : _master (address): 0x01BFd82675DBCc7762C84019cA518e701C0cD07e
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 00000000000000000000000001bfd82675dbcc7762c84019ca518e701c0cd07e
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.