Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
24803207 | 10 hrs ago | Contract Creation | 0 ETH |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
WarpsMetadata
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 99999999 runs
Other Settings:
shanghai EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
//SPDX-License-Identifier: MIT pragma solidity ^0.8.17; import "lib/openzeppelin-contracts/contracts/utils/Base64.sol"; import "./WarpsArt.sol"; import "../interfaces/IWarps.sol"; import "./Utilities.sol"; /** * @title WarpsMetadata * @author Hurls * @notice Renders ERC721 compatible metadata for Warps. */ library WarpsMetadata { /// @dev Render the JSON Metadata for a given Warps token. /// @param tokenId The id of the token to render. /// @param warps The DB containing all warps. function tokenURI(uint256 tokenId, IWarps.Warps storage warps) public view returns (string memory) { IWarps.Warp memory warp = WarpsArt.getWarp(tokenId, warps); // Generate both static and animated versions bytes memory staticSvg = WarpsArt.generateSVG(warp, warps); bytes memory metadata = abi.encodePacked( "{", '"name": "Warps ', Utilities.uint2str(tokenId), '",', '"description": "Up and to the right.",', '"image": ', '"data:image/svg+xml;base64,', Base64.encode(staticSvg), '",', '"attributes": [', attributes(warp), "]", "}" ); return string(abi.encodePacked("data:application/json;base64,", Base64.encode(metadata))); } /// @dev Render the JSON atributes for a given Warps token. /// @param warp The warp to render. function attributes(IWarps.Warp memory warp) public pure returns (bytes memory) { bool showVisualAttributes = warp.hasManyWarps; return abi.encodePacked( showVisualAttributes ? trait("Color Band", colorBand(WarpsArt.colorBandIndex(warp, warp.stored.divisorIndex)), ",") : "", showVisualAttributes ? trait("Gradient", gradients(WarpsArt.gradientIndex(warp, warp.stored.divisorIndex)), ",") : "", trait("Warps", Utilities.uint2str(warp.warpsCount), "") ); } /// @dev Get the names for different gradients. Compare WarpsArt.GRADIENTS. /// @param gradientIndex The index of the gradient. function gradients(uint8 gradientIndex) public pure returns (string memory) { return ["None", "Linear", "Double Linear", "Reflected", "Double Angled", "Angled", "Linear Z"][gradientIndex]; } /// @dev Get the percentage values for different color bands. Compare WarpsArt.COLOR_BANDS. /// @param bandIndex The index of the color band. function colorBand(uint8 bandIndex) public pure returns (string memory) { return ["Eighty", "Sixty", "Forty", "Twenty", "Ten", "Five", "One"][bandIndex]; } /// @dev Generate the SVG snipped for a single attribute. /// @param traitType The `trait_type` for this trait. /// @param traitValue The `value` for this trait. /// @param append Helper to append a comma. function trait(string memory traitType, string memory traitValue, string memory append) public pure returns (string memory) { return string(abi.encodePacked("{", '"trait_type": "', traitType, '",' '"value": "', traitValue, '"' "}", append)); } /// @dev Generate the HTML for the animation_url in the metadata. /// @param tokenId The id of the token to generate the embed for. /// @param svg The rendered SVG code to embed in the HTML. function generateHTML(uint256 tokenId, bytes memory svg) public pure returns (bytes memory) { return abi.encodePacked( "<!DOCTYPE html>", '<html lang="en">', "<head>", '<meta charset="UTF-8">', '<meta http-equiv="X-UA-Compatible" content="IE=edge">', '<meta name="viewport" content="width=device-width, initial-scale=1.0">', "<title>Warp #", Utilities.uint2str(tokenId), "</title>", "<style>", "html,", "body {", "margin: 0;", "background: #EFEFEF;", "overflow: hidden;", "}", "svg {", "max-width: 100vw;", "max-height: 100vh;", "}", "</style>", "</head>", "<body>", svg, "</body>", "</html>" ); } }
// 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 pragma solidity ^0.8.17; import "../interfaces/IWarps.sol"; import "./EightyColors.sol"; import "./Utilities.sol"; /** * @title WarpsArt * @author Hurls * @notice Renders the Warps visuals. */ library WarpsArt { /// @dev The semiperfect divisors of the 80 warps. function divisors() public pure returns (uint8[8] memory) { return [20, 10, 4, 1, 0, 0, 0, 0]; } /// @dev The different color band sizes that we use for the art. function colorBands() public pure returns (uint8[7] memory) { return [80, 60, 40, 20, 10, 5, 1]; } /// @dev The gradient increment steps. function gradients() public pure returns (uint8[7] memory) { return [0, 1, 2, 5, 8, 9, 10]; } /// @dev Load a warp from storage and fill its current state settings. /// @param tokenId The id of the warp to fetch. /// @param warps The DB containing all warps. function getWarp(uint256 tokenId, IWarps.Warps storage warps) public view returns (IWarps.Warp memory warp) { IWarps.StoredWarp memory stored = warps.all[tokenId]; return getWarp(tokenId, stored.divisorIndex, warps); } /// @dev Load a warp from storage and fill its current state settings. /// @param tokenId The id of the warp to fetch. /// @param divisorIndex The divisorindex to get. /// @param warps The DB containing all warps. function getWarp(uint256 tokenId, uint8 divisorIndex, IWarps.Warps storage warps) public view returns (IWarps.Warp memory warp) { IWarps.StoredWarp memory stored = warps.all[tokenId]; stored.divisorIndex = divisorIndex; // Override in case we're fetching specific state. warp.stored = stored; // Set up the source of randomness + seed for this Warp. warp.seed = stored.seed; // Helpers warp.isRoot = divisorIndex == 0; warp.hasManyWarps = divisorIndex < 6; warp.composite = !warp.isRoot && divisorIndex < 7 ? stored.composites[divisorIndex - 1] : 0; // Token properties warp.colorBand = colorBandIndex(warp, divisorIndex); warp.gradient = gradientIndex(warp, divisorIndex); warp.warpsCount = divisors()[divisorIndex]; } /// @dev Query the gradient of a given warp at a certain warp count. /// @param warp The warp we want to get the gradient for. /// @param divisorIndex The warp divisor in question. function gradientIndex(IWarps.Warp memory warp, uint8 divisorIndex) public pure returns (uint8) { uint256 n = Utilities.random(warp.seed, "gradient", 100); return divisorIndex == 0 ? n < 20 ? uint8(1 + (n % 6)) : 0 : divisorIndex < 6 ? warp.stored.gradients[divisorIndex - 1] : 0; } /// @dev Query the color band of a given warp at a certain warp count. /// @param warp The warp we want to get the color band for. /// @param divisorIndex The warp divisor in question. function colorBandIndex(IWarps.Warp memory warp, uint8 divisorIndex) public pure returns (uint8) { uint256 n = Utilities.random(warp.seed, "band", 120); return divisorIndex == 0 ? (n > 80 ? 0 : n > 40 ? 1 : n > 20 ? 2 : n > 10 ? 3 : n > 4 ? 4 : n > 1 ? 5 : 6) : divisorIndex < 6 ? warp.stored.colorBands[divisorIndex - 1] : 6; } /// @dev Generate indexes for the color slots of warp parents (up to the EightyColors.COLORS themselves). /// @param divisorIndex The current divisorIndex to query. /// @param warp The current warp to investigate. /// @param warps The DB containing all warps. function colorIndexes(uint8 divisorIndex, IWarps.Warp memory warp, IWarps.Warps storage warps) public view returns (uint256[] memory) { uint8[8] memory divisors_ = divisors(); uint256 warpsCount = divisors_[divisorIndex]; uint256 seed = warp.seed; uint8 colorBand = colorBands()[colorBandIndex(warp, divisorIndex)]; uint8 gradient = gradients()[gradientIndex(warp, divisorIndex)]; // If we're a composited warp, we choose colors only based on // the slots available in our parents. Otherwise, // we choose based on our available spectrum. uint256 possibleColorChoices = divisorIndex > 0 ? divisors_[divisorIndex - 1] * 2 : 80; // We initialize our index and select the first color uint256[] memory indexes = new uint256[](warpsCount); indexes[0] = Utilities.random(seed, possibleColorChoices); // If we have more than one warp, continue selecting colors if (warp.hasManyWarps) { if (gradient > 0) { // If we're a gradient warp, we select based on the color band looping around // the 80 possible colors for (uint256 i = 1; i < warpsCount;) { indexes[i] = (indexes[0] + (i * gradient * colorBand / warpsCount) % colorBand) % 80; unchecked { ++i; } } } else if (divisorIndex == 0) { // If we select initial non gradient colors, we just take random ones // available in our color band for (uint256 i = 1; i < warpsCount;) { indexes[i] = (indexes[0] + Utilities.random(seed + i, colorBand)) % 80; unchecked { ++i; } } } else { // If we have parent warps, we select our colors from their set for (uint256 i = 1; i < warpsCount;) { indexes[i] = Utilities.random(seed + i, possibleColorChoices); unchecked { ++i; } } } } // We resolve our color indexes through our parent tree until we reach the root warps if (divisorIndex > 0) { uint8 previousDivisor = divisorIndex - 1; // We already have our current warp, but need the our parent state color indices uint256[] memory parentIndexes = colorIndexes(previousDivisor, warp, warps); // We also need to fetch the colors of the warp that was composited into us IWarps.Warp memory composited = getWarp(warp.composite, previousDivisor, warps); uint256[] memory compositedIndexes = colorIndexes(previousDivisor, composited, warps); // Replace random indices with parent / root color indices uint8 count = divisors_[previousDivisor]; // We always select the first color from our parent uint256 initialBranchIndex = indexes[0] % count; indexes[0] = indexes[0] < count ? parentIndexes[initialBranchIndex] : compositedIndexes[initialBranchIndex]; // If we don't have a gradient, we continue resolving from our parent for the remaining warps if (gradient == 0) { for (uint256 i; i < warpsCount;) { uint256 branchIndex = indexes[i] % count; indexes[i] = indexes[i] < count ? parentIndexes[branchIndex] : compositedIndexes[branchIndex]; unchecked { ++i; } } } else { // If we have a gradient we base the remaining colors off our initial selection for (uint256 i = 1; i < warpsCount;) { indexes[i] = (indexes[0] + (i * gradient * colorBand / warpsCount) % colorBand) % 80; unchecked { ++i; } } } } return indexes; } /// @dev Fetch all colors of a given Warp. /// @param warp The warp to get colors for. /// @param warps The DB containing all warps. function colors(IWarps.Warp memory warp, IWarps.Warps storage warps) public view returns (string[] memory, uint256[] memory) { // A fully composited warp has no color. if (warp.stored.divisorIndex == 7) { string[] memory zeroColors = new string[](1); uint256[] memory zeroIndexes = new uint256[](1); zeroColors[0] = "000"; zeroIndexes[0] = 999; return (zeroColors, zeroIndexes); } // Fetch the indices on the original color mapping. uint256[] memory indexes = colorIndexes(warp.stored.divisorIndex, warp, warps); // Map over to get the colors. string[] memory warpColors = new string[](indexes.length); string[80] memory allColors = EightyColors.colors(); // Always set the first color. warpColors[0] = allColors[indexes[0]]; // Resolve each additional check color via their index in EightyColors.COLORS. for (uint256 i = 1; i < indexes.length; i++) { warpColors[i] = allColors[indexes[i]]; } return (warpColors, indexes); } /// @dev Get the number of warps we should display per row. /// @param warps The number of warps in the piece. function perRow(uint8 warps) public pure returns (uint8) { return warps == 80 ? 8 : warps >= 20 ? 4 : warps == 10 || warps == 4 ? 2 : 1; } /// @dev Get the X-offset for positioning warp horizontally. /// @param warps The number of warps in the piece. function rowX(uint8 warps) public pure returns (uint16) { if (warps == 2) { return 310; // Adjusted value to center two warps horizontally } return warps <= 1 ? 286 : warps == 5 ? 304 : warps == 10 || warps == 4 ? 268 : 196; } /// @dev Get the Y-offset for positioning warp vertically. /// @param warps The number of warps in the piece. function rowY(uint8 warps) public pure returns (uint16) { if (warps == 2) { return 270; // Adjusted value to center two warps vertically } return warps > 4 ? 160 : warps == 4 ? 268 : warps > 1 ? 304 : 286; } /// @dev Generate the SVG code for all warps in a given token. /// @param data The data object containing rendering settings. function generateWarps(WarpRenderData memory data) public pure returns (bytes memory) { bytes memory warpsBytes; uint8 warpsCount = data.count; for (uint8 i; i < warpsCount; i++) { // Compute row settings. data.indexInRow = i % data.perRow; data.isNewRow = data.indexInRow == 0 && i > 0; // Compute offsets. if (data.isNewRow) data.rowY += data.spaceY; if (data.isNewRow && data.indent) { if (i == 0) { data.rowX += data.spaceX / 2; } if (i % (data.perRow * 2) == 0) { data.rowX -= data.spaceX / 2; } else { data.rowX += data.spaceX / 2; } } string memory translateX = Utilities.uint2str(data.rowX + data.indexInRow * data.spaceX); string memory translateY = Utilities.uint2str(data.rowY); string memory color = data.colors[i]; // Render the current . warpsBytes = abi.encodePacked( warpsBytes, abi.encodePacked( '<g transform="translate(', translateX, ", ", translateY, ')">', '<g transform="translate(3, 3) scale(', data.scale, ')">', // Outer layer (color) '<path d="M15 26.264c1.271 0 4.012 4.144 5.207 3.703 1.194-.441.668-5.403 1.643-6.233.974-.83 5.698.558 6.334-.56.636-1.117-2.91-4.576-2.69-5.847.221-1.27 4.72-3.29 4.498-4.56-.22-1.271-5.127-1.607-5.763-2.725-.636-1.117 1.53-5.597.556-6.427-.974-.83-4.945 2.114-6.14 1.672C17.45 4.846 16.272 0 15 0c-1.272 0-2.45 4.846-3.645 5.287-1.195.442-5.166-2.502-6.14-1.672-.974.83 1.192 5.31.556 6.427C5.136 11.16.23 11.496.008 12.767c-.22 1.27 4.277 3.29 4.497 4.56.221 1.271-3.325 4.73-2.689 5.847.636 1.118 5.36-.27 6.334.56.974.83.448 5.791 1.643 6.233 1.196.441 3.936-3.703 5.207-3.703Z" fill="#', color, '"/>', // First black layer '<path d="M14.999 24.216c1.04 0 3.283 3.39 4.26 3.03.978-.361.547-4.421 1.345-5.1.797-.679 4.662.456 5.182-.458.52-.915-2.381-3.744-2.2-4.784.18-1.04 3.86-2.691 3.68-3.731-.181-1.04-4.196-1.315-4.716-2.23-.52-.913 1.253-4.58.456-5.258-.797-.679-4.047 1.73-5.025 1.368-.977-.361-1.941-4.326-2.982-4.326-1.04 0-2.004 3.965-2.982 4.326-.977.361-4.227-2.047-5.024-1.368-.797.678.976 4.345.456 5.259-.52.914-4.535 1.19-4.716 2.229-.18 1.04 3.5 2.691 3.68 3.731.18 1.04-2.72 3.87-2.2 4.784.52.914 4.385-.22 5.182.458.797.678.367 4.738 1.344 5.1.978.36 3.22-3.03 4.26-3.03Z" fill="#000"/>', // Middle layer (color) '<path d="M14.998 22.168c.81 0 2.553 2.637 3.314 2.357.76-.281.425-3.44 1.046-3.967.62-.528 3.625.355 4.03-.356.405-.712-1.852-2.912-1.711-3.72.14-.81 3.003-2.094 2.862-2.903-.14-.809-3.263-1.023-3.668-1.734-.404-.711.975-3.562.355-4.09S18.078 9.1 17.318 8.819c-.76-.28-1.51-3.364-2.32-3.364-.809 0-1.558 3.083-2.319 3.364-.76.281-3.288-1.592-3.907-1.064-.62.528.758 3.379.354 4.09-.405.711-3.527.925-3.668 1.734-.14.809 2.722 2.093 2.862 2.902.14.809-2.116 3.01-1.711 3.72.404.712 3.41-.171 4.03.357.62.528.286 3.685 1.046 3.966.76.281 2.505-2.356 3.314-2.356Z" fill="#', color, '"/>', // Inner black layer '<path d="M15.005 20.12c.579 0 1.824 1.884 2.367 1.683.543-.2.304-2.456.747-2.833.443-.377 2.59.254 2.88-.255.288-.508-1.323-2.08-1.223-2.657.1-.578 2.145-1.495 2.044-2.073-.1-.578-2.33-.73-2.62-1.238-.288-.508.696-2.545.254-2.922-.443-.377-2.248.96-2.792.76-.543-.2-1.078-2.403-1.656-2.403-.578 0-1.114 2.202-1.657 2.403-.543.2-2.348-1.137-2.791-.76-.443.377.542 2.414.253 2.922-.29.508-2.52.66-2.62 1.238-.1.578 1.944 1.495 2.044 2.073.1.578-1.511 2.15-1.222 2.657.289.509 2.437-.122 2.88.255.442.377.203 2.632.746 2.833.543.2 1.789-1.683 2.367-1.683Z" fill="#000"/>', // Inner layer (color) '<path d="M15 18.584c.404 0 1.276 1.319 1.656 1.178.38-.14.213-1.719.523-1.983.31-.264 1.813.177 2.015-.178.202-.356-.926-1.456-.855-1.86.07-.405 1.5-1.047 1.43-1.451-.07-.405-1.63-.512-1.833-.867-.203-.356.487-1.782.177-2.046-.31-.264-1.574.673-1.954.532-.38-.14-.755-1.682-1.16-1.682-.404 0-.78 1.542-1.16 1.682-.38.141-1.643-.796-1.953-.532-.31.264.38 1.69.177 2.046-.202.355-1.764.462-1.834.867-.07.404 1.36 1.046 1.431 1.45.07.405-1.058 1.505-.856 1.86.203.356 1.706-.085 2.016.179.31.264.142 1.843.523 1.983.38.14 1.252-1.178 1.656-1.178Z" fill="#', color, '"/>', "</g>", "</g>" ) ); } return warpsBytes; } /// @dev Collect relevant rendering data for easy access across functions. /// @param warp Our current warp loaded from storage. /// @param warps The DB containing all warps. function collectRenderData(IWarps.Warp memory warp, IWarps.Warps storage warps) public view returns (WarpRenderData memory data) { // Carry through base settings. data.warp = warp; data.isBlack = warp.stored.divisorIndex == 7; data.count = data.isBlack ? 1 : divisors()[warp.stored.divisorIndex]; // Compute colors and indexes. (string[] memory colors_, uint256[] memory colorIndexes_) = colors(warp, warps); data.gridColor = "#000000"; data.canvasColor = "#000000"; data.colorIndexes = colorIndexes_; data.colors = colors_; // Compute positioning data. data.scale = data.count > 20 ? "0.528" : data.count > 1 ? "2" : "3"; data.spaceX = data.count == 80 ? 36 : 72; data.spaceY = data.count > 20 ? 36 : 72; data.perRow = perRow(data.count); data.indent = data.count == 40; data.rowX = rowX(data.count); data.rowY = rowY(data.count); } /// @dev Generate the SVG code for rows in the 8x10 Warps grid. function generateGridRow() public pure returns (bytes memory) { bytes memory row; for (uint256 i; i < 8; i++) { row = abi.encodePacked(row, '<use href="#square" x="', Utilities.uint2str(196 + i * 36), '" y="160"/>'); } return row; } /// @dev Generate the SVG code for the entire 8x10 Warps grid. function generateGrid() public pure returns (bytes memory) { bytes memory grid; for (uint256 i; i < 10; i++) { grid = abi.encodePacked(grid, '<use href="#row" y="', Utilities.uint2str(i * 36), '"/>'); } return abi.encodePacked('<g id="grid" x="196" y="160">', grid, "</g>"); } /// @dev Generate the complete SVG code for a given Warp. /// @param warp The warp to render. /// @param warps The DB containing all warps. function generateSVG(IWarps.Warp memory warp, IWarps.Warps storage warps) public view returns (bytes memory) { WarpRenderData memory data = collectRenderData(warp, warps); return abi.encodePacked( "<svg ", 'viewBox="0 0 680 680" ', 'fill="none" xmlns="http://www.w3.org/2000/svg" ', 'style="width:100%;background:black;"', ">", "<defs>", '<rect id="square" width="36" height="36" stroke="', data.gridColor, '"></rect>', '<g id="row">', generateGridRow(), "</g>" "</defs>", '<rect width="680" height="680" fill="black"/>', '<rect x="188" y="152" width="304" height="376" fill="', data.canvasColor, '"/>', generateGrid(), generateWarps(data), "</svg>" ); } } /// @dev Bag holding all data relevant for rendering. struct WarpRenderData { IWarps.Warp warp; uint256[] colorIndexes; string[] colors; string canvasColor; string gridColor; string duration; string scale; uint32 seed; uint16 rowX; uint16 rowY; uint8 count; uint8 spaceX; uint8 spaceY; uint8 perRow; uint8 indexInRow; uint8 isIndented; bool isNewRow; bool isBlack; bool indent; bool isStatic; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; interface IWarps { struct StoredWarp { uint16[6] composites; // The tokenIds that were composited into this one uint8[5] colorBands; // The length of the used color band in percent uint8[5] gradients; // Gradient settings for each generation uint8 divisorIndex; // Easy access to next / previous divisor uint16 seed; // A unique identifier to enable swapping } struct Warp { StoredWarp stored; // We carry over the warp from storage uint256 seed; // The instantiated seed for pseudo-randomisation uint8 warpsCount; // How many warps this token has bool hasManyWarps; // Whether the warp has many warps uint16 composite; // The parent tokenId that was composited into this one bool isRoot; // Whether it has no parents (80 warps) uint8 colorBand; // 100%, 50%, 25%, 12.5%, 6.25%, 5%, 1.25% uint8 gradient; // Linearly through the colorBand [1, 2, 3] } struct Epoch { bool committed; bool revealed; uint64 revealBlock; uint128 randomness; } struct Warps { mapping(uint256 => StoredWarp) all; // All warps mapping(uint256 => Epoch) epochs; // Epoch data for randomness uint32 minted; // The number of warps editions that have been migrated uint32 burned; // The number of tokens that have been burned uint32 currentEpoch; // Current epoch number } event Sacrifice(uint256 indexed burnedId, uint256 indexed tokenId); event Composite(uint256 indexed tokenId, uint256 indexed burnedId, uint8 indexed warps); error NotAllowed(); error InvalidTokenCount(); error BlackWarp__InvalidWarp(); }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.17; library Utilities { /// @dev Zero-index based pseudorandom number based on one input and max bound function random(uint256 input, uint256 _max) internal pure returns (uint256) { return (uint256(keccak256(abi.encodePacked(input))) % _max); } /// @dev Zero-index based salted pseudorandom number based on two inputs and max bound function random(uint256 input, string memory salt, uint256 _max) internal pure returns (uint256) { return (uint256(keccak256(abi.encodePacked(input, salt))) % _max); } /// @dev Convert an integer to a string function uint2str(uint256 _i) internal pure returns (string memory _uintAsString) { if (_i == 0) { return "0"; } uint256 j = _i; uint256 len; while (j != 0) { ++len; j /= 10; } bytes memory bstr = new bytes(len); uint256 k = len; while (_i != 0) { k = k - 1; uint8 temp = (48 + uint8(_i - (_i / 10) * 10)); bytes1 b1 = bytes1(temp); bstr[k] = b1; _i /= 10; } return string(bstr); } /// @dev Get the smallest non zero number function minGt0(uint8 one, uint8 two) internal pure returns (uint8) { return one > two ? two > 0 ? two : one : one; } /// @dev Get the smaller number function min(uint8 one, uint8 two) internal pure returns (uint8) { return one < two ? one : two; } /// @dev Get the larger number function max(uint8 one, uint8 two) internal pure returns (uint8) { return one > two ? one : two; } /// @dev Get the average between two numbers function avg(uint8 one, uint8 two) internal pure returns (uint8 result) { unchecked { result = (one >> 1) + (two >> 1) + (one & two & 1); } } /// @dev Get the days since another date (input is seconds) function day(uint256 from, uint256 to) internal pure returns (uint24) { return uint24((to - from) / 24 hours + 1); } }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.17; /** * @title EightyColors * @author Hurls * @notice The eighty colors of Warps. */ library EightyColors { /// @dev These are sorted in a gradient. function colors() public pure returns (string[80] memory) { return [ // Deep purples to violets "2D0157", "3A0B75", "4C1A9E", "5B28BC", "6B36DB", "7B45F9", "8860FF", "9575FF", "A18CFF", // Blues "0A4BF1", "0E5FFF", "1E74FF", "2E89FF", "3E9EFF", "4EB3FF", "5EC8FF", "6EDDFF", // Teals and Cyans "00B5B5", "00C5C5", "00D5D5", "00E5E5", "00F5F5", // Greens "018A08", "029F0E", "03B414", "04C91A", "05DE20", "06F326", "25FF45", "45FF65", "65FF85", // Yellow-greens "85FF65", "A5FF45", "C5FF25", "E5FF05", // Yellows "FFE600", "FFD800", "FFCA00", "FFBC00", "FFAE00", // Orange "FFA000", "FF9200", "FF8400", "FF7600", "FF6800", // Coral and Salmon "FF5A4F", "FF4C41", "FF3E33", "FF3025", "FF2217", // Reds "FF1409", "F01209", "E11009", "D20E09", "C30C09", // Deep reds "B40A09", "A50809", "960609", "870409", "780209", // Burgundy to pink "690A1E", "7A0F33", "8B1448", "9C195D", "AD1E72", "BE2387", "CF289C", "E02DB1", "F132C6", // Magentas and purples "F23ED1", "F34ADC", "F456E7", "F562F2", "E77AFF", "D886FF", "C992FF", "BA9EFF", "9B89E7", "8C68CF", "7D47B7" ]; } /** * @notice Get the color string at a specific index. * @param _index The index (0-79) of the color to retrieve. * @return The hex string of the color at the specified index. * @dev Reverts if the index is out of bounds. */ function getColorByIndex(uint8 _index) public pure returns (string memory) { require(_index < 80, "Index out of bounds"); return colors()[_index]; } /** * @notice Get the index of a specific color string. * @param _color The hex string of the color to find. * @return The index (0-79) of the color. * @dev Reverts if the color is not found in the list. */ function getIndexByColor(string memory _color) public pure returns (uint8) { string[80] memory _colors = colors(); bytes32 colorHash = keccak256(abi.encodePacked(_color)); for (uint8 i = 0; i < 80; i++) { if (keccak256(abi.encodePacked(_colors[i])) == colorHash) { return i; } } revert("Color not found"); } }
{ "remappings": [ "forge-std/=lib/forge-std/src/", "solady/=lib/solady/src/", "solady-test/=lib/solady/test/", "openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/", "openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "uniswap-v2-core/=lib/uniswap/v2-core/contracts/", "uniswap-v3-core/=lib/uniswap/v3-core/contracts/", "uniswap-v3-periphery/=lib/uniswap/v3-periphery/contracts/", "uniswap-v4-core/=lib/uniswap/v4-core/src/", "uniswap-v4-periphery/=lib/uniswap/v4-periphery/src/", "ds-test/=lib/forge-std/lib/ds-test/src/", "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/", "uniswap/=lib/uniswap/" ], "optimizer": { "enabled": true, "runs": 99999999 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "none", "appendCBOR": false }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "shanghai", "viaIR": true, "libraries": { "src/libraries/EightyColors.sol": { "EightyColors": "0xdF9BAa3097206178fdcB9Bc59d9917e5d89c7F79" }, "src/libraries/WarpsArt.sol": { "WarpsArt": "0x2e02A531215b73182eF8d8dE8245495673Cd078F" }, "src/libraries/WarpsMetadata.sol": { "WarpsMetadata": "0x025996Bf6139AdD64F7808d6cb935034cd07da9c" } } }
Contract ABI
API[{"inputs":[{"components":[{"components":[{"internalType":"uint16[6]","name":"composites","type":"uint16[6]"},{"internalType":"uint8[5]","name":"colorBands","type":"uint8[5]"},{"internalType":"uint8[5]","name":"gradients","type":"uint8[5]"},{"internalType":"uint8","name":"divisorIndex","type":"uint8"},{"internalType":"uint16","name":"seed","type":"uint16"}],"internalType":"struct IWarps.StoredWarp","name":"stored","type":"tuple"},{"internalType":"uint256","name":"seed","type":"uint256"},{"internalType":"uint8","name":"warpsCount","type":"uint8"},{"internalType":"bool","name":"hasManyWarps","type":"bool"},{"internalType":"uint16","name":"composite","type":"uint16"},{"internalType":"bool","name":"isRoot","type":"bool"},{"internalType":"uint8","name":"colorBand","type":"uint8"},{"internalType":"uint8","name":"gradient","type":"uint8"}],"internalType":"struct IWarps.Warp","name":"warp","type":"tuple"}],"name":"attributes","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint8","name":"bandIndex","type":"uint8"}],"name":"colorBand","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"svg","type":"bytes"}],"name":"generateHTML","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint8","name":"gradientIndex","type":"uint8"}],"name":"gradients","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"string","name":"traitType","type":"string"},{"internalType":"string","name":"traitValue","type":"string"},{"internalType":"string","name":"append","type":"string"}],"name":"trait","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"}]
Contract Creation Code
6080806040523461001a57611ce9908161001f823930815050f35b5f80fdfe6080604090808252600480361015610015575f80fd5b5f91823560e01c9081635f5d5f4214610bdb575080638727240614610b9b578063962f363b14610b0b578063b390ef191461065b578063b7773faa146106085763fa7ea71f14610063575f80fd5b827ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610451578035602435732e02a531215b73182ef8d8de8245495673cd078f928551937f492544da00000000000000000000000000000000000000000000000000000000855283828601528260248601526103208086604481855af49586156105fe5790879392918497610464575b50506101329161034491895195869485937f113a1f9700000000000000000000000000000000000000000000000000000000855284018a611096565b6103248301525af49384156104595780946103b2575b50506103ae91610349608f61017161016b61016561034e96611397565b97611163565b9361158b565b9287519384916020987f7b000000000000000000000000000000000000000000000000000000000000008a8501527f226e616d65223a2022576172707320000000000000000000000000000000000060218501526101d8815180928c603088019101610f03565b8301907f222c000000000000000000000000000000000000000000000000000000000000918260308201527f226465736372697074696f6e223a2022557020616e6420746f2074686520726960328201527f6768742e222c000000000000000000000000000000000000000000000000000060528201527f22696d616765223a20000000000000000000000000000000000000000000000060588201527f22646174613a696d6167652f7376672b786d6c3b6261736536342c000000000060618201526102ae825180938d607c85019101610f03565b0190607c8201527f2261747472696275746573223a205b0000000000000000000000000000000000607e8201526102ee825180938b608d85019101610f03565b017f5d00000000000000000000000000000000000000000000000000000000000000608d8201527f7d00000000000000000000000000000000000000000000000000000000000000608e82015203606f810184520182610ea0565b611163565b9261039f603d825180967f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c0000008783015261038f81518092898686019101610f03565b810103601d810187520185610ea0565b51928284938452830190610f24565b0390f35b909193503d8082843e6103c58184610ea0565b8201916020818403126104515780519067ffffffffffffffff8211610455570182601f82011215610451578051916103fc83610f67565b9361040988519586610ea0565b8385526020848401011161044e5750608f61017161016b6101658661043f6103ae99976103499760208061034e9c019101610f03565b98965050505050819350610148565b80fd5b5080fd5b8280fd5b8551903d90823e3d90fd5b919650809293503d83116105f7575b61047d8183610ea0565b8101918183039081126105f35788519261049684610dca565b6102408092126105ef578951906104ac82610e14565b80601f850112156105eb578a516104c281610e4c565b8060c08601918383116105e7579186959493918e938e9a9998905b8382106105b85750509361030093610518846105096101329c9a966103449c9a966105a99a8752611012565b60208501526101608601611012565b908201526105296102008401611004565b606082015261053b6102208401610ff5565b6080820152855281015160208501526105576102608201611004565b8d850152610568610280820161105f565b606085015261057a6102a08201610ff5565b608085015261058c6102c0820161105f565b60a085015261059e6102e08201611004565b60c085015201611004565b60e082015296918193506100f6565b60209294969798999a9b50819395506105d18392610ff5565b8152019101918d999897969594928f94926104dd565b8c80fd5b8980fd5b8880fd5b8780fd5b503d610473565b88513d89823e3d90fd5b828460207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610451576103ae90610648610643610ee1565b6118a0565b9051918291602083526020830190610f24565b5090827ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261044e576024359067ffffffffffffffff821161044e573660238301121561044e576103ae7f3c2f626f64793e0000000000000000000000000000000000000000000000000085610af9610179876106eb6106e4368a84013560248c01610fa1565b9135611397565b9084519586927f3c21444f43545950452068746d6c3e000000000000000000000000000000000060208501527f3c68746d6c206c616e673d22656e223e00000000000000000000000000000000602f8501527f3c686561643e0000000000000000000000000000000000000000000000000000603f8501527f3c6d65746120636861727365743d225554462d38223e0000000000000000000060458501527f3c6d65746120687474702d65717569763d22582d55412d436f6d70617469626c605b8501527f652220636f6e74656e743d2249453d65646765223e0000000000000000000000607b8501527f3c6d657461206e616d653d2276696577706f72742220636f6e74656e743d227760908501527f696474683d6465766963652d77696474682c20696e697469616c2d7363616c6560b08501527f3d312e30223e000000000000000000000000000000000000000000000000000060d08501527f3c7469746c653e5761727020230000000000000000000000000000000000000060d685015261088181518092602060e388019101610f03565b83017f3c2f7469746c653e00000000000000000000000000000000000000000000000060e38201527f3c7374796c653e0000000000000000000000000000000000000000000000000060eb8201527f68746d6c2c00000000000000000000000000000000000000000000000000000060f28201527f626f6479207b000000000000000000000000000000000000000000000000000060f78201527f6d617267696e3a20303b0000000000000000000000000000000000000000000060fd8201527f6261636b67726f756e643a20234546454645463b0000000000000000000000006101078201527f6f766572666c6f773a2068696464656e3b00000000000000000000000000000061011b8201527f7d000000000000000000000000000000000000000000000000000000000000008061012c8301527f737667207b00000000000000000000000000000000000000000000000000000061012d8301527f6d61782d77696474683a2031303076773b0000000000000000000000000000006101328301527f6d61782d6865696768743a2031303076683b00000000000000000000000000006101438301526101558201527f3c2f7374796c653e0000000000000000000000000000000000000000000000006101568201527f3c2f686561643e0000000000000000000000000000000000000000000000000061015e8201527f3c626f64793e0000000000000000000000000000000000000000000000000000610165820152825190610abe8261016b9560208785019101610f03565b01918201527f3c2f68746d6c3e0000000000000000000000000000000000000000000000000061017282015203610159810185520183610ea0565b51918291602083526020830190610f24565b50919060607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261044e5767ffffffffffffffff92803584811161045557610b589036908301610fd7565b93602435818111610b9757610b709036908401610fd7565b9260443591821161044e575091610b916103ae959261064894369101610fd7565b91611bf6565b8380fd5b828460207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610451576103ae90610648610bd6610ee1565b611a4d565b919290507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360161032081126104515761024090610c1884610dca565b1261044e578351610c2881610e14565b3660231215610451578451610c3c81610e4c565b8060c495368711610dab57905b868210610daf57505081523660e3121561045157845193610c6985610e14565b8461016491368311610dab57905b828210610d9357505060209485830152366101831215610455578551610c9c81610e14565b8061020492368411610d8f578790915b848310610d7757505050868301523560ff8116810361045557606082015261ffff90610224358281168103610b97576080820152835261024435848401526102643560ff8116810361045557858401526102843580151581036104555760608401526102a43590811681036104515760808301526102c43580151581036104515760a08301526102e43560ff811681036104515760c0830152610304359060ff8216820361044e575081610d679160e06103ae94015261158b565b9251928284938452830190610f24565b8190610d8284610ef5565b8152019101908790610cac565b8580fd5b60208091610da084610ef5565b815201910190610c77565b8480fd5b813561ffff81168103610d8f57815260209182019101610c49565b610100810190811067ffffffffffffffff821117610de757604052565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b60a0810190811067ffffffffffffffff821117610de757604052565b60e0810190811067ffffffffffffffff821117610de757604052565b60c0810190811067ffffffffffffffff821117610de757604052565b6020810190811067ffffffffffffffff821117610de757604052565b6040810190811067ffffffffffffffff821117610de757604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff821117610de757604052565b6004359060ff82168203610ef157565b5f80fd5b359060ff82168203610ef157565b5f5b838110610f145750505f910152565b8181015183820152602001610f05565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f602093610f6081518092818752878088019101610f03565b0116010190565b67ffffffffffffffff8111610de757601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b929192610fad82610f67565b91610fbb6040519384610ea0565b829481845281830111610ef1578281602093845f960137010152565b9080601f83011215610ef157816020610ff293359101610fa1565b90565b519061ffff82168203610ef157565b519060ff82168203610ef157565b9080601f83011215610ef1576040519161102b83610e14565b829060a08101928311610ef157905b8282106110475750505090565b6020809161105484611004565b81520191019061103a565b51908115158203610ef157565b5f915b6005831061107c57505050565b60019060ff8351168152602080910192019201919061106f565b805180515f90845b600683106111485750505060e0610300926080836110c6602060ff96015160c089019061106c565b6110d9604082015161016089019061106c565b8460608201511661020088015261ffff918291015116610220870152602082015161024087015283604083015116610260870152606082015115156102808701526080820151166102a086015260a081015115156102c08601528260c0820151166102e0860152015116910152565b60019061ffff8351168152602080910192019201919061109e565b805115611384576040516060810181811067ffffffffffffffff821117610de757604052604081527f4142434445464748494a4b4c4d4e4f505152535455565758595a61626364656660208201527f6768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f604082015281516002928382018092116113575760038092049384811b947f3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811603611357579261123b61122586610f67565b956112336040519788610ea0565b808752610f67565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe060208701910136823793829183518401925b83811061130657505050505106806001146112b75760021461128e575090565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff603d91015390565b507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81603d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81940153015390565b85600491979293949701918251600190603f9082828260121c16880101518453828282600c1c16880101518385015382828260061c168801015188850153168501015187820153019592919061126e565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5060405161139181610e68565b5f815290565b80156114fa5780815f925b6114c45750806113b183610f67565b926113bf6040519485610ea0565b8084527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06113ec82610f67565b01366020860137905b6113fe57505090565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8201918211611357578192600a92838204938085029085820414851517156113575782039182116113575760ff80921660300191821161135757855111156114975760f81b7fff00000000000000000000000000000000000000000000000000000000000000165f1a908401601f015390816113f5565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611357576001600a91019204806113a2565b5060405161150781610e84565b600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b90929160ff6103209161154c84610340810197611096565b16910152565b6040519061155f82610e84565b600182527f2c000000000000000000000000000000000000000000000000000000000000006020830152565b606081015115155f815f1461187a57506115dd602060ff60608551015116604051809381927fca0e21730000000000000000000000000000000000000000000000000000000083528760048401611534565b0381732e02a531215b73182ef8d8de8245495673cd078f5af490811561180f575f9161183a575b5061161161165091611a4d565b6040519061161e82610e84565b600a82527f436f6c6f722042616e64000000000000000000000000000000000000000000006020830152610b91611552565b905b5f901561181a575061169c602060ff60608551015116604051809381927fe46970e00000000000000000000000000000000000000000000000000000000083528760048401611534565b0381732e02a531215b73182ef8d8de8245495673cd078f5af490811561180f575f916117bf575b509061172360ff60406117196116db610ff2966118a0565b8251906116e782610e84565b600882527f4772616469656e740000000000000000000000000000000000000000000000006020830152610b91611552565b955b015116611397565b9061177460405161173381610e84565b600581526020937f5761727073000000000000000000000000000000000000000000000000000000858301526040519161176c83610e68565b5f8352611bf6565b604051948261178c8794518092878088019101610f03565b83016117a082518093878085019101610f03565b016117b382518093868085019101610f03565b01038084520182610ea0565b906020823d8211611807575b816117d860209383610ea0565b8101031261044e57509061172360ff60406117196116db6117fb610ff297611004565b959650505050506116c3565b3d91506117cb565b6040513d5f823e3d90fd5b9061172360ff6040610ff29481519061183282610e68565b81529561171b565b906020823d8211611872575b8161185360209383610ea0565b8101031261044e575061161161186b61165092611004565b9150611604565b3d9150611846565b6040519061188782610e68565b815290611652565b9060078110156114975760051b0190565b611a499060ff6040918251926118b584610e30565b7f4c696e656172205a0000000000000000000000000000000000000000000000008151916118e283610e84565b600483526020927f4e6f6e6500000000000000000000000000000000000000000000000000000000848201528652805161191b81610e84565b600681527f4c696e65617200000000000000000000000000000000000000000000000000008482015283870152805161195381610e84565b600d81527f446f75626c65204c696e656172000000000000000000000000000000000000008482015281870152805161198b81610e84565b600981527f5265666c6563746564000000000000000000000000000000000000000000000084820152606087015280516119c481610e84565b600d81527f446f75626c6520416e676c65640000000000000000000000000000000000000084820152608087015280516119fd81610e84565b600681527f416e676c656400000000000000000000000000000000000000000000000000008482015260a08701525191611a3683610e84565b6008835282015260c0840152169061188f565b5190565b611a499060ff604091825192611a6284610e30565b7f4f6e650000000000000000000000000000000000000000000000000000000000815191611a8f83610e84565b600683526020927f45696768747900000000000000000000000000000000000000000000000000008482015286528051611ac881610e84565b600581527f536978747900000000000000000000000000000000000000000000000000000084820152838701528051611b0081610e84565b600581527f466f72747900000000000000000000000000000000000000000000000000000084820152818701528051611b3881610e84565b600681527f5477656e747900000000000000000000000000000000000000000000000000008482015260608701528051611b7181610e84565b600381527f54656e00000000000000000000000000000000000000000000000000000000008482015260808701528051611baa81610e84565b600481527f46697665000000000000000000000000000000000000000000000000000000008482015260a08701525191611be383610e84565b6003835282015260c0840152169061188f565b603e90610ff292936040519485927f7b0000000000000000000000000000000000000000000000000000000000000060208501527f2274726169745f74797065223a202200000000000000000000000000000000006021850152611c64815180926020603088019101610f03565b83017f222c2276616c7565223a202200000000000000000000000000000000000000006030820152611ca0825180936020603c85019101610f03565b017f227d000000000000000000000000000000000000000000000000000000000000603c820152611cda8251809360208785019101610f03565b0103601e810184520182610ea056
Deployed Bytecode
0x6080604090808252600480361015610015575f80fd5b5f91823560e01c9081635f5d5f4214610bdb575080638727240614610b9b578063962f363b14610b0b578063b390ef191461065b578063b7773faa146106085763fa7ea71f14610063575f80fd5b827ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610451578035602435732e02a531215b73182ef8d8de8245495673cd078f928551937f492544da00000000000000000000000000000000000000000000000000000000855283828601528260248601526103208086604481855af49586156105fe5790879392918497610464575b50506101329161034491895195869485937f113a1f9700000000000000000000000000000000000000000000000000000000855284018a611096565b6103248301525af49384156104595780946103b2575b50506103ae91610349608f61017161016b61016561034e96611397565b97611163565b9361158b565b9287519384916020987f7b000000000000000000000000000000000000000000000000000000000000008a8501527f226e616d65223a2022576172707320000000000000000000000000000000000060218501526101d8815180928c603088019101610f03565b8301907f222c000000000000000000000000000000000000000000000000000000000000918260308201527f226465736372697074696f6e223a2022557020616e6420746f2074686520726960328201527f6768742e222c000000000000000000000000000000000000000000000000000060528201527f22696d616765223a20000000000000000000000000000000000000000000000060588201527f22646174613a696d6167652f7376672b786d6c3b6261736536342c000000000060618201526102ae825180938d607c85019101610f03565b0190607c8201527f2261747472696275746573223a205b0000000000000000000000000000000000607e8201526102ee825180938b608d85019101610f03565b017f5d00000000000000000000000000000000000000000000000000000000000000608d8201527f7d00000000000000000000000000000000000000000000000000000000000000608e82015203606f810184520182610ea0565b611163565b9261039f603d825180967f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c0000008783015261038f81518092898686019101610f03565b810103601d810187520185610ea0565b51928284938452830190610f24565b0390f35b909193503d8082843e6103c58184610ea0565b8201916020818403126104515780519067ffffffffffffffff8211610455570182601f82011215610451578051916103fc83610f67565b9361040988519586610ea0565b8385526020848401011161044e5750608f61017161016b6101658661043f6103ae99976103499760208061034e9c019101610f03565b98965050505050819350610148565b80fd5b5080fd5b8280fd5b8551903d90823e3d90fd5b919650809293503d83116105f7575b61047d8183610ea0565b8101918183039081126105f35788519261049684610dca565b6102408092126105ef578951906104ac82610e14565b80601f850112156105eb578a516104c281610e4c565b8060c08601918383116105e7579186959493918e938e9a9998905b8382106105b85750509361030093610518846105096101329c9a966103449c9a966105a99a8752611012565b60208501526101608601611012565b908201526105296102008401611004565b606082015261053b6102208401610ff5565b6080820152855281015160208501526105576102608201611004565b8d850152610568610280820161105f565b606085015261057a6102a08201610ff5565b608085015261058c6102c0820161105f565b60a085015261059e6102e08201611004565b60c085015201611004565b60e082015296918193506100f6565b60209294969798999a9b50819395506105d18392610ff5565b8152019101918d999897969594928f94926104dd565b8c80fd5b8980fd5b8880fd5b8780fd5b503d610473565b88513d89823e3d90fd5b828460207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610451576103ae90610648610643610ee1565b6118a0565b9051918291602083526020830190610f24565b5090827ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261044e576024359067ffffffffffffffff821161044e573660238301121561044e576103ae7f3c2f626f64793e0000000000000000000000000000000000000000000000000085610af9610179876106eb6106e4368a84013560248c01610fa1565b9135611397565b9084519586927f3c21444f43545950452068746d6c3e000000000000000000000000000000000060208501527f3c68746d6c206c616e673d22656e223e00000000000000000000000000000000602f8501527f3c686561643e0000000000000000000000000000000000000000000000000000603f8501527f3c6d65746120636861727365743d225554462d38223e0000000000000000000060458501527f3c6d65746120687474702d65717569763d22582d55412d436f6d70617469626c605b8501527f652220636f6e74656e743d2249453d65646765223e0000000000000000000000607b8501527f3c6d657461206e616d653d2276696577706f72742220636f6e74656e743d227760908501527f696474683d6465766963652d77696474682c20696e697469616c2d7363616c6560b08501527f3d312e30223e000000000000000000000000000000000000000000000000000060d08501527f3c7469746c653e5761727020230000000000000000000000000000000000000060d685015261088181518092602060e388019101610f03565b83017f3c2f7469746c653e00000000000000000000000000000000000000000000000060e38201527f3c7374796c653e0000000000000000000000000000000000000000000000000060eb8201527f68746d6c2c00000000000000000000000000000000000000000000000000000060f28201527f626f6479207b000000000000000000000000000000000000000000000000000060f78201527f6d617267696e3a20303b0000000000000000000000000000000000000000000060fd8201527f6261636b67726f756e643a20234546454645463b0000000000000000000000006101078201527f6f766572666c6f773a2068696464656e3b00000000000000000000000000000061011b8201527f7d000000000000000000000000000000000000000000000000000000000000008061012c8301527f737667207b00000000000000000000000000000000000000000000000000000061012d8301527f6d61782d77696474683a2031303076773b0000000000000000000000000000006101328301527f6d61782d6865696768743a2031303076683b00000000000000000000000000006101438301526101558201527f3c2f7374796c653e0000000000000000000000000000000000000000000000006101568201527f3c2f686561643e0000000000000000000000000000000000000000000000000061015e8201527f3c626f64793e0000000000000000000000000000000000000000000000000000610165820152825190610abe8261016b9560208785019101610f03565b01918201527f3c2f68746d6c3e0000000000000000000000000000000000000000000000000061017282015203610159810185520183610ea0565b51918291602083526020830190610f24565b50919060607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261044e5767ffffffffffffffff92803584811161045557610b589036908301610fd7565b93602435818111610b9757610b709036908401610fd7565b9260443591821161044e575091610b916103ae959261064894369101610fd7565b91611bf6565b8380fd5b828460207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610451576103ae90610648610bd6610ee1565b611a4d565b919290507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360161032081126104515761024090610c1884610dca565b1261044e578351610c2881610e14565b3660231215610451578451610c3c81610e4c565b8060c495368711610dab57905b868210610daf57505081523660e3121561045157845193610c6985610e14565b8461016491368311610dab57905b828210610d9357505060209485830152366101831215610455578551610c9c81610e14565b8061020492368411610d8f578790915b848310610d7757505050868301523560ff8116810361045557606082015261ffff90610224358281168103610b97576080820152835261024435848401526102643560ff8116810361045557858401526102843580151581036104555760608401526102a43590811681036104515760808301526102c43580151581036104515760a08301526102e43560ff811681036104515760c0830152610304359060ff8216820361044e575081610d679160e06103ae94015261158b565b9251928284938452830190610f24565b8190610d8284610ef5565b8152019101908790610cac565b8580fd5b60208091610da084610ef5565b815201910190610c77565b8480fd5b813561ffff81168103610d8f57815260209182019101610c49565b610100810190811067ffffffffffffffff821117610de757604052565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b60a0810190811067ffffffffffffffff821117610de757604052565b60e0810190811067ffffffffffffffff821117610de757604052565b60c0810190811067ffffffffffffffff821117610de757604052565b6020810190811067ffffffffffffffff821117610de757604052565b6040810190811067ffffffffffffffff821117610de757604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff821117610de757604052565b6004359060ff82168203610ef157565b5f80fd5b359060ff82168203610ef157565b5f5b838110610f145750505f910152565b8181015183820152602001610f05565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f602093610f6081518092818752878088019101610f03565b0116010190565b67ffffffffffffffff8111610de757601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b929192610fad82610f67565b91610fbb6040519384610ea0565b829481845281830111610ef1578281602093845f960137010152565b9080601f83011215610ef157816020610ff293359101610fa1565b90565b519061ffff82168203610ef157565b519060ff82168203610ef157565b9080601f83011215610ef1576040519161102b83610e14565b829060a08101928311610ef157905b8282106110475750505090565b6020809161105484611004565b81520191019061103a565b51908115158203610ef157565b5f915b6005831061107c57505050565b60019060ff8351168152602080910192019201919061106f565b805180515f90845b600683106111485750505060e0610300926080836110c6602060ff96015160c089019061106c565b6110d9604082015161016089019061106c565b8460608201511661020088015261ffff918291015116610220870152602082015161024087015283604083015116610260870152606082015115156102808701526080820151166102a086015260a081015115156102c08601528260c0820151166102e0860152015116910152565b60019061ffff8351168152602080910192019201919061109e565b805115611384576040516060810181811067ffffffffffffffff821117610de757604052604081527f4142434445464748494a4b4c4d4e4f505152535455565758595a61626364656660208201527f6768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f604082015281516002928382018092116113575760038092049384811b947f3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811603611357579261123b61122586610f67565b956112336040519788610ea0565b808752610f67565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe060208701910136823793829183518401925b83811061130657505050505106806001146112b75760021461128e575090565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff603d91015390565b507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81603d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81940153015390565b85600491979293949701918251600190603f9082828260121c16880101518453828282600c1c16880101518385015382828260061c168801015188850153168501015187820153019592919061126e565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5060405161139181610e68565b5f815290565b80156114fa5780815f925b6114c45750806113b183610f67565b926113bf6040519485610ea0565b8084527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06113ec82610f67565b01366020860137905b6113fe57505090565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8201918211611357578192600a92838204938085029085820414851517156113575782039182116113575760ff80921660300191821161135757855111156114975760f81b7fff00000000000000000000000000000000000000000000000000000000000000165f1a908401601f015390816113f5565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611357576001600a91019204806113a2565b5060405161150781610e84565b600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b90929160ff6103209161154c84610340810197611096565b16910152565b6040519061155f82610e84565b600182527f2c000000000000000000000000000000000000000000000000000000000000006020830152565b606081015115155f815f1461187a57506115dd602060ff60608551015116604051809381927fca0e21730000000000000000000000000000000000000000000000000000000083528760048401611534565b0381732e02a531215b73182ef8d8de8245495673cd078f5af490811561180f575f9161183a575b5061161161165091611a4d565b6040519061161e82610e84565b600a82527f436f6c6f722042616e64000000000000000000000000000000000000000000006020830152610b91611552565b905b5f901561181a575061169c602060ff60608551015116604051809381927fe46970e00000000000000000000000000000000000000000000000000000000083528760048401611534565b0381732e02a531215b73182ef8d8de8245495673cd078f5af490811561180f575f916117bf575b509061172360ff60406117196116db610ff2966118a0565b8251906116e782610e84565b600882527f4772616469656e740000000000000000000000000000000000000000000000006020830152610b91611552565b955b015116611397565b9061177460405161173381610e84565b600581526020937f5761727073000000000000000000000000000000000000000000000000000000858301526040519161176c83610e68565b5f8352611bf6565b604051948261178c8794518092878088019101610f03565b83016117a082518093878085019101610f03565b016117b382518093868085019101610f03565b01038084520182610ea0565b906020823d8211611807575b816117d860209383610ea0565b8101031261044e57509061172360ff60406117196116db6117fb610ff297611004565b959650505050506116c3565b3d91506117cb565b6040513d5f823e3d90fd5b9061172360ff6040610ff29481519061183282610e68565b81529561171b565b906020823d8211611872575b8161185360209383610ea0565b8101031261044e575061161161186b61165092611004565b9150611604565b3d9150611846565b6040519061188782610e68565b815290611652565b9060078110156114975760051b0190565b611a499060ff6040918251926118b584610e30565b7f4c696e656172205a0000000000000000000000000000000000000000000000008151916118e283610e84565b600483526020927f4e6f6e6500000000000000000000000000000000000000000000000000000000848201528652805161191b81610e84565b600681527f4c696e65617200000000000000000000000000000000000000000000000000008482015283870152805161195381610e84565b600d81527f446f75626c65204c696e656172000000000000000000000000000000000000008482015281870152805161198b81610e84565b600981527f5265666c6563746564000000000000000000000000000000000000000000000084820152606087015280516119c481610e84565b600d81527f446f75626c6520416e676c65640000000000000000000000000000000000000084820152608087015280516119fd81610e84565b600681527f416e676c656400000000000000000000000000000000000000000000000000008482015260a08701525191611a3683610e84565b6008835282015260c0840152169061188f565b5190565b611a499060ff604091825192611a6284610e30565b7f4f6e650000000000000000000000000000000000000000000000000000000000815191611a8f83610e84565b600683526020927f45696768747900000000000000000000000000000000000000000000000000008482015286528051611ac881610e84565b600581527f536978747900000000000000000000000000000000000000000000000000000084820152838701528051611b0081610e84565b600581527f466f72747900000000000000000000000000000000000000000000000000000084820152818701528051611b3881610e84565b600681527f5477656e747900000000000000000000000000000000000000000000000000008482015260608701528051611b7181610e84565b600381527f54656e00000000000000000000000000000000000000000000000000000000008482015260808701528051611baa81610e84565b600481527f46697665000000000000000000000000000000000000000000000000000000008482015260a08701525191611be383610e84565b6003835282015260c0840152169061188f565b603e90610ff292936040519485927f7b0000000000000000000000000000000000000000000000000000000000000060208501527f2274726169745f74797065223a202200000000000000000000000000000000006021850152611c64815180926020603088019101610f03565b83017f222c2276616c7565223a202200000000000000000000000000000000000000006030820152611ca0825180936020603c85019101610f03565b017f227d000000000000000000000000000000000000000000000000000000000000603c820152611cda8251809360208785019101610f03565b0103601e810184520182610ea056
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.