ETH Price: $3,294.66 (-1.07%)

Contract

0x75Cd3F538c091C1D514aB1aD9832f54198CAceC0
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
0x588568ab797017b22b0f680c8cde3bd59170dbb7874794ce9450e9dab8604b78 Assert Ownership(pending)2024-12-23 5:04:352 hrs ago1734930275IN
Gnars HD: GNARSHD Token
0 ETH(Pending)(Pending)
0x2b4a83edb4b2d83255650f985634ebb386022874c9e1795011f6c0235b498dbb Assert Ownership(pending)2024-12-23 4:40:013 hrs ago1734928801IN
Gnars HD: GNARSHD Token
0 ETH(Pending)(Pending)
0x06d2b4e1575bca758f9321c6891d51db5741935df5a47a04c50fcda734cbd76b Assert Ownership(pending)2024-12-23 3:40:514 hrs ago1734925251IN
Gnars HD: GNARSHD Token
0 ETH(Pending)(Pending)
0x443e299e62249325a8c529d2120d501becc9d03f23c26df7d89b3c5c857f0b0b Assert Ownership(pending)2024-12-22 17:31:4314 hrs ago1734888703IN
Gnars HD: GNARSHD Token
0 ETH(Pending)(Pending)
0xdcd9ab3f86bdfb281a31f3d1f3a830d1ccf308d02185e771449eff549f367092 Assert Ownership(pending)2024-12-22 16:38:4015 hrs ago1734885520IN
Gnars HD: GNARSHD Token
0 ETH(Pending)(Pending)
0x1eaec2db992506606dec8314eefb754d8ce99de7d9236fdfa39b9f2dda248b52 Assert Ownership(pending)2024-12-22 15:35:0916 hrs ago1734881709IN
Gnars HD: GNARSHD Token
0 ETH(Pending)(Pending)
0x6f447719e1a761533ea1d71444fe3be06d802786675aca3ec071edab4a80b3c4 Assert Ownership(pending)2024-12-22 12:26:0919 hrs ago1734870369IN
Gnars HD: GNARSHD Token
0 ETH(Pending)(Pending)
0x24be44c9855d30211b9bc5353b2b593883b2157ed14ed4e56a1111b1846a8765 Assert Ownership(pending)2024-12-22 12:08:5119 hrs ago1734869331IN
Gnars HD: GNARSHD Token
0 ETH(Pending)(Pending)
0xf5cff604b0c6b1d85cac831902c42297b6d38d2351602db5c7909f2e69684aaf Assert Ownership(pending)2024-12-22 12:08:5119 hrs ago1734869331IN
Gnars HD: GNARSHD Token
0 ETH(Pending)(Pending)
0x4b8a4e95a3e8b9aa9de19334b7bc83fa6a65128642b3ad2e2237abe49af1c5c5 Assert Ownership(pending)2024-12-22 9:35:0522 hrs ago1734860105IN
Gnars HD: GNARSHD Token
0 ETH(Pending)(Pending)
0x7bbda8fbd26c72b8fae452915e6cce770aabe566d862a8c0948dc5bccdcfa563 Assert Ownership(pending)2024-12-22 3:23:3928 hrs ago1734837819IN
Gnars HD: GNARSHD Token
0 ETH(Pending)(Pending)
0x085e864de73a26f15effc8cd5e871171c07e7a1c4ab561b25da3797a6f22438f Assert Ownership(pending)2024-12-22 2:59:4128 hrs ago1734836381IN
Gnars HD: GNARSHD Token
0 ETH(Pending)(Pending)
Assert Ownership214574492024-12-22 10:30:1121 hrs ago1734863411IN
Gnars HD: GNARSHD Token
0 ETH0.000166935.2
Assert Ownership214574382024-12-22 10:27:5921 hrs ago1734863279IN
Gnars HD: GNARSHD Token
0 ETH0.000188655.87669901
Assert Ownership214571482024-12-22 9:29:2322 hrs ago1734859763IN
Gnars HD: GNARSHD Token
0 ETH0.000157294.9
Assert Ownership214570252024-12-22 9:04:3522 hrs ago1734858275IN
Gnars HD: GNARSHD Token
0 ETH0.000154084.8
Assert Ownership214570212024-12-22 9:03:4722 hrs ago1734858227IN
Gnars HD: GNARSHD Token
0 ETH0.000148064.61223285
Assert Ownership214569522024-12-22 8:49:4722 hrs ago1734857387IN
Gnars HD: GNARSHD Token
0 ETH0.000173125.39303047
Assert Ownership214568942024-12-22 8:38:1123 hrs ago1734856691IN
Gnars HD: GNARSHD Token
0 ETH0.000176565.5
Assert Ownership214555802024-12-22 4:14:2327 hrs ago1734840863IN
Gnars HD: GNARSHD Token
0 ETH0.000199046.20026811
Assert Ownership214545462024-12-22 0:46:3530 hrs ago1734828395IN
Gnars HD: GNARSHD Token
0 ETH0.000170145.3
Assert Ownership214542172024-12-21 23:40:3532 hrs ago1734824435IN
Gnars HD: GNARSHD Token
0 ETH0.000173355.4
Assert Ownership214534602024-12-21 21:07:2334 hrs ago1734815243IN
Gnars HD: GNARSHD Token
0 ETH0.000182985.7
Assert Ownership214533932024-12-21 20:53:3534 hrs ago1734814415IN
Gnars HD: GNARSHD Token
0 ETH0.000189675.90863866
Assert Ownership214533932024-12-21 20:53:3534 hrs ago1734814415IN
Gnars HD: GNARSHD Token
0 ETH0.0001915.95
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
GnarsHD

Compiler Version
v0.8.21+commit.d9974bed

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 6 : GnarsHD.sol
// SPDX-License-Identifier: CC0-1.0
pragma solidity 0.8.21;

/// @title Gnars HD
/// @notice High definition Gnars counterparts
/// @author Volky
/// @dev This contract describes Gnars HD as 1:1 counterparts for each GnarV2. They are not mintable, since the ownership of the respective GnarV2 is mirrored on the GnarHD.
///
////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                        //
//                                                                                        //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▀       ▀▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▀   ▄▄░░░░▄   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▀▀       ▀▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▀  ▄▒░░░░░░░░░▌  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▀  ▄▐▒░░░░   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▀  ▀░▐░░░░░░░░▌▐  ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  ▄▒░░░░░░░▐   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓   ▌░ ░░░░░░░░░░▓  ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  ▄░░░░░░░░░▌▌  ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▌  ▄▒ ▒░░░░░░░░░░▌  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▓  ▐░ ░░░░░░▐▐▌▌  ▐▓▓▓▓▓▓▓▓▓▓▓▓▓   ░ ▐░░░░░░░░░░▓   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▓  ▌ ▐░░░░░░░░░▓   ▓▓▓▓▓▓▓▓▓▓▓▓   ▓▒ ░░░░░░░░░░▐   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▌  ▒ ░░░░░░░░░░▐   ▓▓▓▓▓▓▓▓▓▓▓▓   ▌░▒░░░░░░░░░░▌  ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▌  ▒ ░░░░░░░░░░▐   ▓▓▀▀▀         ▐░ ░░░░░░░░░░▐   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▌  ▒ ▐░░░░░░░░░░        ▄▄▄▄▄▄▄▄▄▐░░░░░░░░░░░░▌  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▌  ▌░▐░░░░░░░░░░▌   ▐░ ░░░░░░░░░░▌░░░░░░░░░░░▐  ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▓  ▐░ ▒░░░░░░░░░░▄▄░░░░░░░░░░░░░░▌░░░░░░░░░░▌▌  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌  ▌▒░░░░░░░░░░░▓░░░░░░░░░░░░░░░▌░░░░░░░░░░▒▌  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓   ▒░░░░░░░░░░░▌░░░░░▄▄▀▀▀▀▀▀▀▀▀▒░░░░░░░░░▀▄   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌  ▐░░░░░░░░░░░▌░░░░▀░░░░░░░░░░░░░░░░░░░░░░░░▌  ▀▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌  ▐░░░░░░░░░░▒░░░▌▒▒░░░░░░░░░░░░░░░░░░░░░░░░▀  ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  ▐░░░░░░░░░▒░░░▌▄▐░░░░░░░░░░░░░░░░░░░░░░░░▒▌  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓   ▒░░░░░░░░▓░░░░▓░▄░▀▒░░░░░░░░░░░░░░░░░░░▒▐▐  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓   ░░░░░░░░░░▌░░░░░▀▀▒▄▄▄▄▄▄▄▓▀▀▒░░░░░░░░░░░▐  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  ▐░░░░░░░░░░░▒▀▄▄░▄▄░▀░░░░░░░░░░░░░░░░░░░░░▌  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  ▐░░░░░░░░░░░░░░░░▓░░░░░░░░░░░░░░░░░░░░░░░▌  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓   ▒░░░░░░░░░░░░░░░▒░░░░░░░░░░░░░░░░░░░░░░▀  ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  ▐░░░░░░░░░░░░░░░▒░░░░░░░░░░░░░░░░░░░░▄▀  ▄▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌   ▒░░░░░░░░░░░░░▀▒░░░░░░░░░░░░░░░░░▒▀  ▄▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓   █▀▀▄▄▄░░░░░░░░░▀▄░░░░░░░░░░░▄▄█   ▄▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌  ▐░░░░░░░░░░░░░░░░░▒▀▀▀▀▀▀▒░░░░▐   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓   ▀░░░░░░░░░░░░░░░░░░░░░░░░░▄▀  ▄▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▄   ▀▀▒▄░░░░░░░░░░░░░░░▒▀▀   ▄▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▄                     ▄▄▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▄▄▄▄▄▄▄▄▄▄▄▄▄▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//    ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓    //
//                                                                                        //
//              ░██████╗░███╗░░██╗░█████╗░██████╗░░██████╗  ██╗░░██╗██████╗░              //
//              ██╔════╝░████╗░██║██╔══██╗██╔══██╗██╔════╝  ██║░░██║██╔══██╗              //
//              ██║░░██╗░██╔██╗██║███████║██████╔╝╚█████╗░  ███████║██║░░██║              //
//              ██║░░╚██╗██║╚████║██╔══██║██╔══██╗░╚═══██╗  ██╔══██║██║░░██║              //
//              ╚██████╔╝██║░╚███║██║░░██║██║░░██║██████╔╝  ██║░░██║██████╔╝              //
//              ░╚═════╝░╚═╝░░╚══╝╚═╝░░╚═╝╚═╝░░╚═╝╚═════╝░  ╚═╝░░╚═╝╚═════╝░              //
//                                                                                        //
//                                                                                        //
////////////////////////////////////////////////////////////////////////////////////////////

import {Strings} from "openzeppelin-contracts/contracts/utils/Strings.sol";
import {Owned} from "solmate/auth/Owned.sol";
import {Base64} from "base64/base64.sol";

contract GnarsHD is Owned {
    /* ⌐◨—————————————————————————————————————————————————————————————◨
                         STRUCTS / EVENTS / ERRORS
       ⌐◨—————————————————————————————————————————————————————————————◨ */
    struct Artwork {
        string ipfsFolder;
        uint48 amountBackgrounds;
        uint48 amountBodies;
        uint48 amountAccessories;
        uint48 amountHeads;
        uint48 amountNoggles;
    }

    event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);

    error Untransferable();
    error TokenDoesNotExist(uint256 tokenId);

    /* ⌐◨—————————————————————————————————————————————————————————————◨
                         STORAGE
       ⌐◨—————————————————————————————————————————————————————————————◨ */

    string public name = "Gnars HD";

    string public symbol = "GNARSHD";

    string public rendererBaseUri;

    string public contractURI;

    Artwork public artwork;

    ISkateContractV2 public gnarsV2;

    /* ⌐◨—————————————————————————————————————————————————————————————◨
                        CONSTRUCTOR
       ⌐◨—————————————————————————————————————————————————————————————◨ */

    constructor(
        address _gnarsV2Address,
        string memory _rendererBaseUri,
        Artwork memory _artwork,
        string memory _contractURI,
        address _owner
    ) Owned(_owner) {
        gnarsV2 = ISkateContractV2(_gnarsV2Address);
        rendererBaseUri = _rendererBaseUri;
        artwork = _artwork;
        contractURI = _contractURI;
    }

    /* ⌐◨—————————————————————————————————————————————————————————————◨
                         MAIN LOGIC
       ⌐◨—————————————————————————————————————————————————————————————◨ */

    function setArtwork(Artwork memory _artwork) public onlyOwner {
        artwork = _artwork;
    }

    function setContractUri(string memory _contractURI) public onlyOwner {
        contractURI = _contractURI;
    }

    function setRendererBaseUri(string memory _rendererBaseUri) public onlyOwner {
        rendererBaseUri = _rendererBaseUri;
    }

    /// @notice The properties and query string for a generated token
    /// @param _tokenId The ERC-721 token id
    function getAttributes(uint256 _tokenId)
        public
        view
        returns (string memory resultAttributes, string memory queryString)
    {
        (uint48 background, uint48 body, uint48 accessory, uint48 head, uint48 glasses) = gnarsV2.seeds(_tokenId);
        IGnarDescriptorV2 descriptor = IGnarDescriptorV2(gnarsV2.descriptor());
        IGnarDecorator decorator = IGnarDecorator(descriptor.decorator());

        queryString = string.concat(
            "?contractAddress=",
            Strings.toHexString(address(this)),
            "&tokenId=",
            Strings.toString(_tokenId),
            getBackgroundQueryParam(background),
            getPartQueryParam("BODY", body, artwork.amountBodies),
            getPartQueryParam("ACCESSORY", accessory, artwork.amountAccessories),
            getPartQueryParam("HEADS", head, artwork.amountHeads),
            getPartQueryParam("NOGGLES", glasses, artwork.amountNoggles)
        );

        resultAttributes = string.concat(
            getPartTrait("Background", background, decorator.backgrounds),
            ",",
            getPartTrait("Body", body, decorator.bodies),
            ",",
            getPartTrait("Accessory", accessory, decorator.accessories),
            ",",
            getPartTrait("Head", head, decorator.heads),
            ",",
            getPartTrait("Glasses", glasses, decorator.glasses)
        );
    }

    function getPartQueryParam(string memory folder, uint48 partIndex, uint48 amountOfPart)
        public
        view
        returns (string memory)
    {
        if (partIndex >= amountOfPart) {
            return string.concat("&images=", artwork.ipfsFolder, "/", folder, "/FALLBACK.PNG");
        }

        return string.concat("&images=", artwork.ipfsFolder, "/", folder, "/", Strings.toString(partIndex), ".PNG");
    }

    function getBackgroundQueryParam(uint48 backgroundIndex) public view returns (string memory) {
        if (backgroundIndex >= artwork.amountBackgrounds) {
            return string.concat("&images=", artwork.ipfsFolder, "/BACKGROUND/FALLBACK.PNG");
        }

        return string.concat("&images=", artwork.ipfsFolder, "/BACKGROUND/", Strings.toString(backgroundIndex), ".PNG");
    }

    function getPartTrait(
        string memory traitType,
        uint48 partIndex,
        function (uint256) external view returns (string memory) getPartDescription
    ) public view returns (string memory) {
        try getPartDescription(partIndex) returns (string memory partDescription) {
            return string.concat('{"trait_type":"', traitType, '","value":"', partDescription, '"}');
        } catch {
            return string.concat('{"trait_type":"', traitType, '","value":"Unknown"}');
        }
    }

    function tokenURI(uint256 _tokenId) public view returns (string memory) {
        if (gnarsV2.ownerOf(_tokenId) == address(0)) {
            revert TokenDoesNotExist(_tokenId);
        }

        (string memory attributes, string memory queryString) = getAttributes(_tokenId);
        return string(
            abi.encodePacked(
                "data:application/json;base64,",
                Base64.encode(
                    bytes(
                        abi.encodePacked(
                            '{"name":"Gnar HD #',
                            Strings.toString(_tokenId),
                            '", "description":"High definition Gnar #',
                            Strings.toString(_tokenId),
                            " counterpart",
                            '", "attributes": [',
                            attributes,
                            '], "image": "',
                            string.concat(rendererBaseUri, queryString),
                            '"}'
                        )
                    )
                )
            )
        );
    }

    /* ⌐◨—————————————————————————————————————————————————————————————◨
                              PASSTHROUGH METHODS
       ⌐◨—————————————————————————————————————————————————————————————◨ */

    /// @notice Returns the total amount of Gnars HD in existence
    /// @dev Delegates to the Gnars V2 contract
    function totalSupply() external view returns (uint256) {
        return gnarsV2.totalSupply();
    }

    /// @notice Returns the tokenId of the Gnar HD by index
    /// @dev Delegates to the Gnars V2 contract
    function tokenByIndex(uint256 _index) external view returns (uint256) {
        return gnarsV2.tokenByIndex(_index);
    }

    /// @notice Returns the Gnar HD owner's address by token index
    /// @dev Delegates to the Gnars V2 contract
    function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256) {
        return gnarsV2.tokenOfOwnerByIndex(_owner, _index);
    }

    /// @notice Returns the Gnar HD owner's address by token id
    /// @dev Delegates to the Gnars V2 contract
    function ownerOf(uint256 id) public view returns (address owner) {
        return gnarsV2.ownerOf(id);
    }

    /// @notice Returns the amount of Gnars HD owned by the specified address
    /// @dev Delegates to the Gnars V2 contract
    function balanceOf(address owner) public view returns (uint256) {
        return gnarsV2.balanceOf(owner);
    }

    /// @notice Refresh ownership of specified tokens on marketplaces/datasets that are showing out of date information
    /// @dev Since this token is not mintable, there's no Transfer event. This method emits the Transfer event so that consumers that can detect the creation/new ownership of the token.
    /// @param tokenIds The ids of tokens to refresh
    function assertOwnership(uint256[] memory tokenIds) public {
        for (uint256 i = 0; i < tokenIds.length; i++) {
            uint256 tokenId = tokenIds[i];
            emit Transfer(address(0), gnarsV2.ownerOf(tokenId), tokenId);
        }
    }

    /* ⌐◨—————————————————————————————————————————————————————————————◨
                              ERC721 LOGIC
       ⌐◨—————————————————————————————————————————————————————————————◨ */

    /// @notice Gnars HD are not transferable
    /// @dev Will always revert
    function approve(address, uint256) public pure {
        revert Untransferable();
    }

    /// @notice Gnars HD are not transferable
    /// @dev Will always revert
    function setApprovalForAll(address, bool) public pure {
        revert Untransferable();
    }

    /// @notice Gnars HD are not transferable
    /// @dev Will always revert
    function transferFrom(address, address, uint256) public pure {
        revert Untransferable();
    }

    /// @notice Gnars HD are not transferable
    /// @dev Will always revert
    function safeTransferFrom(address, address, uint256) public pure {
        revert Untransferable();
    }

    /// @notice Gnars HD are not transferable
    /// @dev Will always revert
    function safeTransferFrom(address, address, uint256, bytes calldata) public pure {
        revert Untransferable();
    }

    /* ⌐◨—————————————————————————————————————————————————————————————◨
                              ERC6454 LOGIC
       ⌐◨—————————————————————————————————————————————————————————————◨ */

    /// @notice Gnars HD are not transferable
    /// @dev Will always return false
    function isTransferable(uint256, address, address) external pure returns (bool) {
        return false;
    }

    /* ⌐◨—————————————————————————————————————————————————————————————◨
                              ERC165 LOGIC
       ⌐◨—————————————————————————————————————————————————————————————◨ */

    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
        return interfaceId == 0x01ffc9a7 // ERC165 Interface ID for ERC165
            || interfaceId == 0x80ac58cd // ERC165 Interface ID for ERC721
            || interfaceId == 0x5b5e139f // ERC165 Interface ID for ERC721Metadata
            || interfaceId == 0x780e9d63 // ERC165 Interface ID for ERC721Enumerable
            || interfaceId == 0x7f5828d0 // ERC165 Interface ID for ERC173
            || interfaceId == 0x91a6262f; // ERC165 Interface ID for ERC6454
    }
}

interface IGnarDecorator {
    function accessories(uint256) external view returns (string memory);
    function backgrounds(uint256) external view returns (string memory);
    function bodies(uint256) external view returns (string memory);
    function glasses(uint256) external view returns (string memory);
    function heads(uint256) external view returns (string memory);
}

interface IGnarDescriptorV2 {
    function decorator() external view returns (address);
}

interface ISkateContractV2 {
    function balanceOf(address owner) external view returns (uint256);
    function descriptor() external view returns (address);
    function ownerOf(uint256 tokenId) external view returns (address);
    function seeds(uint256)
        external
        view
        returns (uint48 background, uint48 body, uint48 accessory, uint48 head, uint48 glasses);
    function tokenByIndex(uint256 index) external view returns (uint256);
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);
    function totalSupply() external view returns (uint256);
}

File 2 of 6 : Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

import "./math/Math.sol";
import "./math/SignedMath.sol";

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        unchecked {
            uint256 length = Math.log10(value) + 1;
            string memory buffer = new string(length);
            uint256 ptr;
            /// @solidity memory-safe-assembly
            assembly {
                ptr := add(buffer, add(32, length))
            }
            while (true) {
                ptr--;
                /// @solidity memory-safe-assembly
                assembly {
                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `int256` to its ASCII `string` decimal representation.
     */
    function toString(int256 value) internal pure returns (string memory) {
        return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value))));
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        unchecked {
            return toHexString(value, Math.log256(value) + 1);
        }
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }

    /**
     * @dev Returns true if the two strings are equal.
     */
    function equal(string memory a, string memory b) internal pure returns (bool) {
        return keccak256(bytes(a)) == keccak256(bytes(b));
    }
}

File 3 of 6 : Owned.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Simple single owner authorization mixin.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Owned.sol)
abstract contract Owned {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event OwnershipTransferred(address indexed user, address indexed newOwner);

    /*//////////////////////////////////////////////////////////////
                            OWNERSHIP STORAGE
    //////////////////////////////////////////////////////////////*/

    address public owner;

    modifier onlyOwner() virtual {
        require(msg.sender == owner, "UNAUTHORIZED");

        _;
    }

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(address _owner) {
        owner = _owner;

        emit OwnershipTransferred(address(0), _owner);
    }

    /*//////////////////////////////////////////////////////////////
                             OWNERSHIP LOGIC
    //////////////////////////////////////////////////////////////*/

    function transferOwnership(address newOwner) public virtual onlyOwner {
        owner = newOwner;

        emit OwnershipTransferred(msg.sender, newOwner);
    }
}

File 4 of 6 : base64.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0;

/// @title Base64
/// @author Brecht Devos - <[email protected]>
/// @notice Provides functions for encoding/decoding base64
library Base64 {
    string internal constant TABLE_ENCODE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
    bytes  internal constant TABLE_DECODE = hex"0000000000000000000000000000000000000000000000000000000000000000"
                                            hex"00000000000000000000003e0000003f3435363738393a3b3c3d000000000000"
                                            hex"00000102030405060708090a0b0c0d0e0f101112131415161718190000000000"
                                            hex"001a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132330000000000";

    function encode(bytes memory data) internal pure returns (string memory) {
        if (data.length == 0) return '';

        // load the table into memory
        string memory table = TABLE_ENCODE;

        // multiply by 4/3 rounded up
        uint256 encodedLen = 4 * ((data.length + 2) / 3);

        // add some extra buffer at the end required for the writing
        string memory result = new string(encodedLen + 32);

        assembly {
            // set the actual output length
            mstore(result, encodedLen)

            // prepare the lookup table
            let tablePtr := add(table, 1)

            // input ptr
            let dataPtr := data
            let endPtr := add(dataPtr, mload(data))

            // result ptr, jump over length
            let resultPtr := add(result, 32)

            // run over the input, 3 bytes at a time
            for {} lt(dataPtr, endPtr) {}
            {
                // read 3 bytes
                dataPtr := add(dataPtr, 3)
                let input := mload(dataPtr)

                // write 4 characters
                mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))
                resultPtr := add(resultPtr, 1)
                mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))
                resultPtr := add(resultPtr, 1)
                mstore8(resultPtr, mload(add(tablePtr, and(shr( 6, input), 0x3F))))
                resultPtr := add(resultPtr, 1)
                mstore8(resultPtr, mload(add(tablePtr, and(        input,  0x3F))))
                resultPtr := add(resultPtr, 1)
            }

            // padding with '='
            switch mod(mload(data), 3)
            case 1 { mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) }
            case 2 { mstore(sub(resultPtr, 1), shl(248, 0x3d)) }
        }

        return result;
    }

    function decode(string memory _data) internal pure returns (bytes memory) {
        bytes memory data = bytes(_data);

        if (data.length == 0) return new bytes(0);
        require(data.length % 4 == 0, "invalid base64 decoder input");

        // load the table into memory
        bytes memory table = TABLE_DECODE;

        // every 4 characters represent 3 bytes
        uint256 decodedLen = (data.length / 4) * 3;

        // add some extra buffer at the end required for the writing
        bytes memory result = new bytes(decodedLen + 32);

        assembly {
            // padding with '='
            let lastBytes := mload(add(data, mload(data)))
            if eq(and(lastBytes, 0xFF), 0x3d) {
                decodedLen := sub(decodedLen, 1)
                if eq(and(lastBytes, 0xFFFF), 0x3d3d) {
                    decodedLen := sub(decodedLen, 1)
                }
            }

            // set the actual output length
            mstore(result, decodedLen)

            // prepare the lookup table
            let tablePtr := add(table, 1)

            // input ptr
            let dataPtr := data
            let endPtr := add(dataPtr, mload(data))

            // result ptr, jump over length
            let resultPtr := add(result, 32)

            // run over the input, 4 characters at a time
            for {} lt(dataPtr, endPtr) {}
            {
               // read 4 characters
               dataPtr := add(dataPtr, 4)
               let input := mload(dataPtr)

               // write 3 bytes
               let output := add(
                   add(
                       shl(18, and(mload(add(tablePtr, and(shr(24, input), 0xFF))), 0xFF)),
                       shl(12, and(mload(add(tablePtr, and(shr(16, input), 0xFF))), 0xFF))),
                   add(
                       shl( 6, and(mload(add(tablePtr, and(shr( 8, input), 0xFF))), 0xFF)),
                               and(mload(add(tablePtr, and(        input , 0xFF))), 0xFF)
                    )
                )
                mstore(resultPtr, shl(232, output))
                resultPtr := add(resultPtr, 3)
            }
        }

        return result;
    }
}

File 5 of 6 : Math.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                // Solidity will revert if denominator == 0, unlike the div opcode on its own.
                // The surrounding unchecked block does not change this fact.
                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1, "Math: mulDiv overflow");

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10 ** 64) {
                value /= 10 ** 64;
                result += 64;
            }
            if (value >= 10 ** 32) {
                value /= 10 ** 32;
                result += 32;
            }
            if (value >= 10 ** 16) {
                value /= 10 ** 16;
                result += 16;
            }
            if (value >= 10 ** 8) {
                value /= 10 ** 8;
                result += 8;
            }
            if (value >= 10 ** 4) {
                value /= 10 ** 4;
                result += 4;
            }
            if (value >= 10 ** 2) {
                value /= 10 ** 2;
                result += 2;
            }
            if (value >= 10 ** 1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256, rounded down, of a positive value.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
        }
    }
}

File 6 of 6 : SignedMath.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard signed math utilities missing in the Solidity language.
 */
library SignedMath {
    /**
     * @dev Returns the largest of two signed numbers.
     */
    function max(int256 a, int256 b) internal pure returns (int256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two signed numbers.
     */
    function min(int256 a, int256 b) internal pure returns (int256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two signed numbers without overflow.
     * The result is rounded towards zero.
     */
    function average(int256 a, int256 b) internal pure returns (int256) {
        // Formula from the book "Hacker's Delight"
        int256 x = (a & b) + ((a ^ b) >> 1);
        return x + (int256(uint256(x) >> 255) & (a ^ b));
    }

    /**
     * @dev Returns the absolute unsigned value of a signed value.
     */
    function abs(int256 n) internal pure returns (uint256) {
        unchecked {
            // must be unchecked in order to support `n = type(int256).min`
            return uint256(n >= 0 ? n : -n);
        }
    }
}

Settings
{
  "remappings": [
    "base64/=lib/base64/",
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
    "forge-std/=lib/forge-std/src/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/",
    "openzeppelin/=lib/openzeppelin-contracts/contracts/",
    "solmate/=lib/solmate/src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "paris",
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_gnarsV2Address","type":"address"},{"internalType":"string","name":"_rendererBaseUri","type":"string"},{"components":[{"internalType":"string","name":"ipfsFolder","type":"string"},{"internalType":"uint48","name":"amountBackgrounds","type":"uint48"},{"internalType":"uint48","name":"amountBodies","type":"uint48"},{"internalType":"uint48","name":"amountAccessories","type":"uint48"},{"internalType":"uint48","name":"amountHeads","type":"uint48"},{"internalType":"uint48","name":"amountNoggles","type":"uint48"}],"internalType":"struct GnarsHD.Artwork","name":"_artwork","type":"tuple"},{"internalType":"string","name":"_contractURI","type":"string"},{"internalType":"address","name":"_owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"TokenDoesNotExist","type":"error"},{"inputs":[],"name":"Untransferable","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"artwork","outputs":[{"internalType":"string","name":"ipfsFolder","type":"string"},{"internalType":"uint48","name":"amountBackgrounds","type":"uint48"},{"internalType":"uint48","name":"amountBodies","type":"uint48"},{"internalType":"uint48","name":"amountAccessories","type":"uint48"},{"internalType":"uint48","name":"amountHeads","type":"uint48"},{"internalType":"uint48","name":"amountNoggles","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"assertOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getAttributes","outputs":[{"internalType":"string","name":"resultAttributes","type":"string"},{"internalType":"string","name":"queryString","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint48","name":"backgroundIndex","type":"uint48"}],"name":"getBackgroundQueryParam","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"folder","type":"string"},{"internalType":"uint48","name":"partIndex","type":"uint48"},{"internalType":"uint48","name":"amountOfPart","type":"uint48"}],"name":"getPartQueryParam","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"traitType","type":"string"},{"internalType":"uint48","name":"partIndex","type":"uint48"},{"internalType":"function (uint256) view external returns (string)","name":"getPartDescription","type":"function"}],"name":"getPartTrait","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gnarsV2","outputs":[{"internalType":"contract ISkateContractV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"isTransferable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rendererBaseUri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"bool","name":"","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"ipfsFolder","type":"string"},{"internalType":"uint48","name":"amountBackgrounds","type":"uint48"},{"internalType":"uint48","name":"amountBodies","type":"uint48"},{"internalType":"uint48","name":"amountAccessories","type":"uint48"},{"internalType":"uint48","name":"amountHeads","type":"uint48"},{"internalType":"uint48","name":"amountNoggles","type":"uint48"}],"internalType":"struct GnarsHD.Artwork","name":"_artwork","type":"tuple"}],"name":"setArtwork","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_contractURI","type":"string"}],"name":"setContractUri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_rendererBaseUri","type":"string"}],"name":"setRendererBaseUri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60c0604052600860809081526711db985c9cc8121160c21b60a05260019062000029908262000279565b5060408051808201909152600781526611d3905494d21160ca1b602082015260029062000057908262000279565b503480156200006557600080fd5b5060405162002bb238038062002bb2833981016040819052620000889162000464565b600080546001600160a01b0319166001600160a01b03831690811782556040518392907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350600780546001600160a01b0319166001600160a01b0387161790556003620000fa858262000279565b5082518390600590819062000110908262000279565b5060208201516001909101805460408401516060850151608086015160a09096015165ffffffffffff908116600160c01b0265ffffffffffff60c01b19978216600160901b0265ffffffffffff60901b199383166c010000000000000000000000000293909316600160601b600160c01b03199483166601000000000000026001600160601b0319909616929097169190911793909317919091169390931792909217929092161790556004620001c8838262000279565b505050505050620005ae565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620001ff57607f821691505b6020821081036200022057634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200027457600081815260208120601f850160051c810160208610156200024f5750805b601f850160051c820191505b8181101562000270578281556001016200025b565b5050505b505050565b81516001600160401b03811115620002955762000295620001d4565b620002ad81620002a68454620001ea565b8462000226565b602080601f831160018114620002e55760008415620002cc5750858301515b600019600386901b1c1916600185901b17855562000270565b600085815260208120601f198616915b828110156200031657888601518255948401946001909101908401620002f5565b5085821015620003355787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b80516001600160a01b03811681146200035d57600080fd5b919050565b60405160c081016001600160401b0381118282101715620003875762000387620001d4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620003b857620003b8620001d4565b604052919050565b600082601f830112620003d257600080fd5b81516001600160401b03811115620003ee57620003ee620001d4565b602062000404601f8301601f191682016200038d565b82815285828487010111156200041957600080fd5b60005b83811015620004395785810183015182820184015282016200041c565b506000928101909101919091529392505050565b805165ffffffffffff811681146200035d57600080fd5b600080600080600060a086880312156200047d57600080fd5b620004888662000345565b60208701519095506001600160401b0380821115620004a657600080fd5b620004b489838a01620003c0565b95506040880151915080821115620004cb57600080fd5b9087019060c0828a031215620004e057600080fd5b620004ea62000362565b825182811115620004fa57600080fd5b620005088b828601620003c0565b82525062000519602084016200044d565b60208201526200052c604084016200044d565b60408201526200053f606084016200044d565b606082015262000552608084016200044d565b60808201526200056560a084016200044d565b60a082015260608901519095509150808211156200058257600080fd5b506200059188828901620003c0565b925050620005a26080870162000345565b90509295509295909350565b6125f480620005be6000396000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c80636352211e11610104578063ae1e6339116100a2578063ccb4807b11610071578063ccb4807b146103c4578063e8a3d485146103d7578063f180aa09146103df578063f2fde38b146103f257600080fd5b8063ae1e633914610388578063b88d4fde1461039b578063bb7a1215146103a9578063c87b56dd146103b157600080fd5b806391a6262f116100de57806391a6262f1461034857806395d89b411461035f578063a060b43b14610367578063a22cb4651461037a57600080fd5b80636352211e146102f757806370a08231146103225780638da5cb5b1461033557600080fd5b806326cc133e1161017157806342842e0e1161014b57806342842e0e146102625780634378a6e3146102b057806344d6c593146102d15780634f6ccce7146102e457600080fd5b806326cc133e146102705780632ec251a71461028a5780632f745c591461029d57600080fd5b806318160ddd116101ad57806318160ddd146102265780631a4d35351461023c5780631ce75adb1461024f57806323b872dd1461026257600080fd5b806301ffc9a7146101d457806306fdde03146101fc578063095ea7b314610211575b600080fd5b6101e76101e2366004611636565b610405565b60405190151581526020015b60405180910390f35b6102046104a8565b6040516101f391906116b0565b61022461021f3660046116db565b610536565b005b61022e61054f565b6040519081526020016101f3565b61022461024a366004611775565b6105c2565b61020461025d3660046118bb565b6106b6565b61022461021f36600461193e565b610278610779565b6040516101f39695949392919061197f565b6102046102983660046119cb565b610843565b61022e6102ab3660046116db565b6108a7565b6102c36102be3660046119e8565b610924565b6040516101f3929190611a01565b6102046102df366004611a2f565b610cfa565b61022e6102f23660046119e8565b610d7b565b61030a6103053660046119e8565b610dea565b6040516001600160a01b0390911681526020016101f3565b61022e610330366004611a92565b610e58565b60005461030a906001600160a01b031681565b6101e7610356366004611aaf565b60009392505050565b610204610e8b565b610224610375366004611ae6565b610e98565b61022461021f366004611b1a565b610224610396366004611b58565b610ed7565b61022461021f366004611c28565b610204610fbf565b6102046103bf3660046119e8565b610fcc565b6102246103d2366004611ae6565b6110ff565b610204611135565b60075461030a906001600160a01b031681565b610224610400366004611a92565b611142565b60006301ffc9a760e01b6001600160e01b03198316148061043657506380ac58cd60e01b6001600160e01b03198316145b806104515750635b5e139f60e01b6001600160e01b03198316145b8061046c575063780e9d6360e01b6001600160e01b03198316145b8061048757506307f5828d60e41b6001600160e01b03198316145b806104a257506391a6262f60e01b6001600160e01b03198316145b92915050565b600180546104b590611cc6565b80601f01602080910402602001604051908101604052809291908181526020018280546104e190611cc6565b801561052e5780601f106105035761010080835404028352916020019161052e565b820191906000526020600020905b81548152906001019060200180831161051157829003601f168201915b505050505081565b60405163072b78c760e01b815260040160405180910390fd5b600754604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd9160048083019260209291908290030181865afa158015610599573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105bd9190611d00565b905090565b60005b81518110156106b25760008282815181106105e2576105e2611d19565b60209081029190910101516007546040516331a9108f60e11b81526004810183905291925082916001600160a01b0390911690636352211e90602401602060405180830381865afa15801561063b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065f9190611d2f565b6001600160a01b031660006001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a450806106aa81611d62565b9150506105c5565b5050565b6040516001600160e01b031960e083901b16815265ffffffffffff8416600482015260609083908390602401600060405180830381865afa92505050801561072057506040513d6000823e601f3d908101601f1916820160405261071d9190810190611d7b565b60015b61074b57846040516020016107359190611de8565b6040516020818303038152906040529050610771565b858160405160200161075e929190611e3e565b6040516020818303038152906040529150505b949350505050565b60058054819061078890611cc6565b80601f01602080910402602001604051908101604052809291908181526020018280546107b490611cc6565b80156108015780601f106107d657610100808354040283529160200191610801565b820191906000526020600020905b8154815290600101906020018083116107e457829003601f168201915b5050506001909301549192505065ffffffffffff80821691600160301b8104821691600160601b8204811691600160901b8104821691600160c01b9091041686565b60065460609065ffffffffffff908116908316106108835760405161086d90600590602001611f22565b6040516020818303038152906040529050919050565b600561089665ffffffffffff84166111b7565b60405160200161086d929190611f6c565b600754604051632f745c5960e01b81526001600160a01b038481166004830152602482018490526000921690632f745c5990604401602060405180830381865afa1580156108f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061091d9190611d00565b9392505050565b6007546040516301e0a07d60e71b815260048101839052606091829160009182918291829182916001600160a01b03169063f0503e809060240160a060405180830381865afa15801561097b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061099f9190611fcb565b945094509450945094506000600760009054906101000a90046001600160a01b03166001600160a01b031663303e74df6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109fe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a229190611d2f565b90506000816001600160a01b0316632065ce0b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a889190611d2f565b9050610a9330611249565b610a9c8b6111b7565b610aa589610843565b604080518082019091526004815263424f445960e01b6020820152600654610ade91908b90600160301b900465ffffffffffff16610cfa565b6040805180820190915260098152684143434553534f525960b81b6020820152600654610b1c91908b90600160601b900465ffffffffffff16610cfa565b604080518082019091526005815264484541445360d81b6020820152600654610b5691908b90600160901b900465ffffffffffff16610cfa565b6040805180820190915260078152664e4f47474c455360c81b6020820152600654610b9291908b90600160c01b900465ffffffffffff16610cfa565b604051602001610ba89796959493929190612040565b60408051601f19818403018152828201909152600a825269109858dad9dc9bdd5b9960b21b60208301529850610bed90886001600160a01b0384166304bde4dd6106b6565b610c2260405180604001604052806004815260200163426f647960e01b81525088846001600160a01b03166344cee73c6106b6565b610c5c604051806040016040528060098152602001684163636573736f727960b81b81525088856001600160a01b0316637ca942106106b6565b610c91604051806040016040528060048152602001631219585960e21b81525088866001600160a01b0316635a503f136106b6565b610cc960405180604001604052806007815260200166476c617373657360c81b81525088876001600160a01b031663b982d1b96106b6565b604051602001610cdd959493929190612110565b604051602081830303815290604052985050505050505050915091565b60608165ffffffffffff168365ffffffffffff1610610d3d57604051610d279060059086906020016121a6565b604051602081830303815290604052905061091d565b600584610d5165ffffffffffff86166111b7565b604051602001610d6393929190612203565b60405160208183030381529060405290509392505050565b600754604051634f6ccce760e01b8152600481018390526000916001600160a01b031690634f6ccce7906024015b602060405180830381865afa158015610dc6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104a29190611d00565b6007546040516331a9108f60e11b8152600481018390526000916001600160a01b031690636352211e90602401602060405180830381865afa158015610e34573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104a29190611d2f565b6007546040516370a0823160e01b81526001600160a01b03838116600483015260009216906370a0823190602401610da9565b600280546104b590611cc6565b6000546001600160a01b03163314610ecb5760405162461bcd60e51b8152600401610ec290612274565b60405180910390fd5b60036106b282826122e9565b6000546001600160a01b03163314610f015760405162461bcd60e51b8152600401610ec290612274565b805181906005908190610f1490826122e9565b5060208201516001909101805460408401516060850151608086015160a09096015165ffffffffffff908116600160c01b0265ffffffffffff60c01b19978216600160901b0265ffffffffffff60901b19938316600160601b02939093166bffffffffffffffffffffffff60601b19948316600160301b026bffffffffffffffffffffffff199096169290971691909117939093179190911693909317929092179290921617905550565b600380546104b590611cc6565b6007546040516331a9108f60e11b8152600481018390526060916000916001600160a01b0390911690636352211e90602401602060405180830381865afa15801561101b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061103f9190611d2f565b6001600160a01b0316036110695760405163c927e5bf60e01b815260048101839052602401610ec2565b60008061107584610924565b915091506110d7611085856111b7565b61108e866111b7565b846003856040516020016110a39291906123a8565b60408051601f19818403018152908290526110c3949392916020016123cd565b60405160208183030381529060405261125f565b6040516020016110e791906124d6565b60405160208183030381529060405292505050919050565b6000546001600160a01b031633146111295760405162461bcd60e51b8152600401610ec290612274565b60046106b282826122e9565b600480546104b590611cc6565b6000546001600160a01b0316331461116c5760405162461bcd60e51b8152600401610ec290612274565b600080546001600160a01b0319166001600160a01b0383169081178255604051909133917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a350565b606060006111c4836113c3565b60010190506000816001600160401b038111156111e3576111e3611707565b6040519080825280601f01601f19166020018201604052801561120d576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461121757509392505050565b60606104a26001600160a01b038316601461149b565b6060815160000361127e57505060408051602081019091526000815290565b600060405180606001604052806040815260200161257f60409139905060006003845160026112ad919061251b565b6112b7919061252e565b6112c2906004612550565b905060006112d182602061251b565b6001600160401b038111156112e8576112e8611707565b6040519080825280601f01601f191660200182016040528015611312576020820181803683370190505b509050818152600183018586518101602084015b8183101561137e576003830192508251603f8160121c168501518253600182019150603f81600c1c168501518253600182019150603f8160061c168501518253600182019150603f8116850151825350600101611326565b60038951066001811461139857600281146113a9576113b5565b613d3d60f01b6001198301526113b5565b603d60f81b6000198301525b509398975050505050505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106114025772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef8100000000831061142e576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061144c57662386f26fc10000830492506010015b6305f5e1008310611464576305f5e100830492506008015b612710831061147857612710830492506004015b6064831061148a576064830492506002015b600a83106104a25760010192915050565b606060006114aa836002612550565b6114b590600261251b565b6001600160401b038111156114cc576114cc611707565b6040519080825280601f01601f1916602001820160405280156114f6576020820181803683370190505b509050600360fc1b8160008151811061151157611511611d19565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061154057611540611d19565b60200101906001600160f81b031916908160001a9053506000611564846002612550565b61156f90600161251b565b90505b60018111156115e7576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106115a3576115a3611d19565b1a60f81b8282815181106115b9576115b9611d19565b60200101906001600160f81b031916908160001a90535060049490941c936115e081612567565b9050611572565b50831561091d5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610ec2565b60006020828403121561164857600080fd5b81356001600160e01b03198116811461091d57600080fd5b60005b8381101561167b578181015183820152602001611663565b50506000910152565b6000815180845261169c816020860160208601611660565b601f01601f19169290920160200192915050565b60208152600061091d6020830184611684565b6001600160a01b03811681146116d857600080fd5b50565b600080604083850312156116ee57600080fd5b82356116f9816116c3565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b038111828210171561173f5761173f611707565b60405290565b604051601f8201601f191681016001600160401b038111828210171561176d5761176d611707565b604052919050565b6000602080838503121561178857600080fd5b82356001600160401b038082111561179f57600080fd5b818501915085601f8301126117b357600080fd5b8135818111156117c5576117c5611707565b8060051b91506117d6848301611745565b81815291830184019184810190888411156117f057600080fd5b938501935b8385101561180e578435825293850193908501906117f5565b98975050505050505050565b60006001600160401b0382111561183357611833611707565b50601f01601f191660200190565b600082601f83011261185257600080fd5b81356118656118608261181a565b611745565b81815284602083860101111561187a57600080fd5b816020850160208301376000918101602001919091529392505050565b65ffffffffffff811681146116d857600080fd5b80356118b681611897565b919050565b600080600080606085870312156118d157600080fd5b84356001600160401b038111156118e757600080fd5b6118f387828801611841565b945050602085013561190481611897565b9250604085013567ffffffffffffffff198116811461192257600080fd5b8060601c925063ffffffff8160401c1691505092959194509250565b60008060006060848603121561195357600080fd5b833561195e816116c3565b9250602084013561196e816116c3565b929592945050506040919091013590565b60c08152600061199260c0830189611684565b65ffffffffffff97881660208401529587166040830152509285166060840152908416608083015290921660a090920191909152919050565b6000602082840312156119dd57600080fd5b813561091d81611897565b6000602082840312156119fa57600080fd5b5035919050565b604081526000611a146040830185611684565b8281036020840152611a268185611684565b95945050505050565b600080600060608486031215611a4457600080fd5b83356001600160401b03811115611a5a57600080fd5b611a6686828701611841565b9350506020840135611a7781611897565b91506040840135611a8781611897565b809150509250925092565b600060208284031215611aa457600080fd5b813561091d816116c3565b600080600060608486031215611ac457600080fd5b833592506020840135611ad6816116c3565b91506040840135611a87816116c3565b600060208284031215611af857600080fd5b81356001600160401b03811115611b0e57600080fd5b61077184828501611841565b60008060408385031215611b2d57600080fd5b8235611b38816116c3565b915060208301358015158114611b4d57600080fd5b809150509250929050565b600060208284031215611b6a57600080fd5b81356001600160401b0380821115611b8157600080fd5b9083019060c08286031215611b9557600080fd5b611b9d61171d565b823582811115611bac57600080fd5b611bb887828601611841565b82525060208301359150611bcb82611897565b81602082015260408301359150611be182611897565b81604082015260608301359150611bf782611897565b816060820152611c09608084016118ab565b6080820152611c1a60a084016118ab565b60a082015295945050505050565b600080600080600060808688031215611c4057600080fd5b8535611c4b816116c3565b94506020860135611c5b816116c3565b93506040860135925060608601356001600160401b0380821115611c7e57600080fd5b818801915088601f830112611c9257600080fd5b813581811115611ca157600080fd5b896020828501011115611cb357600080fd5b9699959850939650602001949392505050565b600181811c90821680611cda57607f821691505b602082108103611cfa57634e487b7160e01b600052602260045260246000fd5b50919050565b600060208284031215611d1257600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b600060208284031215611d4157600080fd5b815161091d816116c3565b634e487b7160e01b600052601160045260246000fd5b600060018201611d7457611d74611d4c565b5060010190565b600060208284031215611d8d57600080fd5b81516001600160401b03811115611da357600080fd5b8201601f81018413611db457600080fd5b8051611dc26118608261181a565b818152856020838501011115611dd757600080fd5b611a26826020830160208601611660565b6e3d913a3930b4ba2fba3cb832911d1160891b81528151600090611e1381600f850160208701611660565b73222c2276616c7565223a22556e6b6e6f776e227d60601b600f939091019283015250602301919050565b6e3d913a3930b4ba2fba3cb832911d1160891b81528251600090611e6981600f850160208801611660565b6a1116113b30b63ab2911d1160a91b600f918401918201528351611e9481601a840160208801611660565b61227d60f01b601a9290910191820152601c01949350505050565b60008154611ebc81611cc6565b60018281168015611ed45760018114611ee957611f18565b60ff1984168752821515830287019450611f18565b8560005260208060002060005b85811015611f0f5781548a820152908401908201611ef6565b50505082870194505b5050505092915050565b6726696d616765733d60c01b81526000611f3f6008830184611eaf565b7f2f4241434b47524f554e442f46414c4c4241434b2e504e47000000000000000081526018019392505050565b6726696d616765733d60c01b81526000611f896008830185611eaf565b6b2f4241434b47524f554e442f60a01b81528351611fae81600c840160208801611660565b632e504e4760e01b600c9290910191820152601001949350505050565b600080600080600060a08688031215611fe357600080fd5b8551611fee81611897565b6020870151909550611fff81611897565b604087015190945061201081611897565b606087015190935061202181611897565b608087015190925061203281611897565b809150509295509295909350565b703f636f6e7472616374416464726573733d60781b815260008851602061206d8260118601838e01611660565b81840191506826746f6b656e49643d60b81b6011830152601a8a5161209781838601858f01611660565b8a519301926120ab81838601858e01611660565b89519301926120bf81838601858d01611660565b88519301926120d381838601858c01611660565b87519301926120e781838601858b01611660565b86519301926120fb81838601858a01611660565b929092019091019a9950505050505050505050565b60008651612122818460208b01611660565b8083019050600b60fa1b8082528751612142816001850160208c01611660565b60019201918201819052865161215f816002850160208b01611660565b60029201918201819052855161217c816003850160208a01611660565b60039201918201528351612197816004840160208801611660565b01600401979650505050505050565b6726696d616765733d60c01b815260006121c36008830185611eaf565b602f60f81b815283516121dd816001840160208801611660565b6c2f46414c4c4241434b2e504e4760981b60019290910191820152600e01949350505050565b6726696d616765733d60c01b815260006122206008830186611eaf565b602f60f81b808252855161223b816001850160208a01611660565b60019201918201528351612256816002840160208801611660565b632e504e4760e01b6002929091019182015260060195945050505050565b6020808252600c908201526b15539055551213d49256915160a21b604082015260600190565b601f8211156122e457600081815260208120601f850160051c810160208610156122c15750805b601f850160051c820191505b818110156122e0578281556001016122cd565b5050505b505050565b81516001600160401b0381111561230257612302611707565b612316816123108454611cc6565b8461229a565b602080601f83116001811461234b57600084156123335750858301515b600019600386901b1c1916600185901b1785556122e0565b600085815260208120601f198616915b8281101561237a5788860151825594840194600190910190840161235b565b50858210156123985787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006123b48285611eaf565b83516123c4818360208801611660565b01949350505050565b717b226e616d65223a22476e6172204844202360701b815284516000906123fb816012850160208a01611660565b7f222c20226465736372697074696f6e223a224869676820646566696e6974696f601291840191820152676e20476e6172202360c01b6032820152855161244981603a840160208a01611660565b6b0818dbdd5b9d195c9c185c9d60a21b603a929091019182015271222c202261747472696275746573223a205b60701b60468201528451612491816058840160208901611660565b6c2e96101134b6b0b3b2911d101160991b6058929091019182015283516124bf816065840160208801611660565b61180e60658284010161227d60f01b815260020190565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081526000825161250e81601d850160208701611660565b91909101601d0192915050565b808201808211156104a2576104a2611d4c565b60008261254b57634e487b7160e01b600052601260045260246000fd5b500490565b80820281158282048414176104a2576104a2611d4c565b60008161257657612576611d4c565b50600019019056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220b0a852002ace2edfe8b5a17b5dda48285d33a004ab58247d8ace1b0ea440fa8064736f6c63430008150033000000000000000000000000558bfff0d583416f7c4e380625c7865821b8e95c00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000240000000000000000000000000e43ffd378684568236d63728c60b492bc53700d5000000000000000000000000000000000000000000000000000000000000002968747470733a2f2f6170692e7a6f72612e636f2f72656e64657265722f737461636b2d696d61676573000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000009900000000000000000000000000000000000000000000000000000000000000eb00000000000000000000000000000000000000000000000000000000000000440000000000000000000000000000000000000000000000000000000000000042697066733a2f2f6261667962656962726b776b613772376b6a6f66766c61646c6b737770347a7a6b61626e336e686d6b65646b6c6274796c6e6a75676877326d36650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000042697066733a2f2f6261666b726569656c336d617070757a6c646236726f666b64777874356577707434336e72686c33797834756c70706e79373533733662616e6e61000000000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101cf5760003560e01c80636352211e11610104578063ae1e6339116100a2578063ccb4807b11610071578063ccb4807b146103c4578063e8a3d485146103d7578063f180aa09146103df578063f2fde38b146103f257600080fd5b8063ae1e633914610388578063b88d4fde1461039b578063bb7a1215146103a9578063c87b56dd146103b157600080fd5b806391a6262f116100de57806391a6262f1461034857806395d89b411461035f578063a060b43b14610367578063a22cb4651461037a57600080fd5b80636352211e146102f757806370a08231146103225780638da5cb5b1461033557600080fd5b806326cc133e1161017157806342842e0e1161014b57806342842e0e146102625780634378a6e3146102b057806344d6c593146102d15780634f6ccce7146102e457600080fd5b806326cc133e146102705780632ec251a71461028a5780632f745c591461029d57600080fd5b806318160ddd116101ad57806318160ddd146102265780631a4d35351461023c5780631ce75adb1461024f57806323b872dd1461026257600080fd5b806301ffc9a7146101d457806306fdde03146101fc578063095ea7b314610211575b600080fd5b6101e76101e2366004611636565b610405565b60405190151581526020015b60405180910390f35b6102046104a8565b6040516101f391906116b0565b61022461021f3660046116db565b610536565b005b61022e61054f565b6040519081526020016101f3565b61022461024a366004611775565b6105c2565b61020461025d3660046118bb565b6106b6565b61022461021f36600461193e565b610278610779565b6040516101f39695949392919061197f565b6102046102983660046119cb565b610843565b61022e6102ab3660046116db565b6108a7565b6102c36102be3660046119e8565b610924565b6040516101f3929190611a01565b6102046102df366004611a2f565b610cfa565b61022e6102f23660046119e8565b610d7b565b61030a6103053660046119e8565b610dea565b6040516001600160a01b0390911681526020016101f3565b61022e610330366004611a92565b610e58565b60005461030a906001600160a01b031681565b6101e7610356366004611aaf565b60009392505050565b610204610e8b565b610224610375366004611ae6565b610e98565b61022461021f366004611b1a565b610224610396366004611b58565b610ed7565b61022461021f366004611c28565b610204610fbf565b6102046103bf3660046119e8565b610fcc565b6102246103d2366004611ae6565b6110ff565b610204611135565b60075461030a906001600160a01b031681565b610224610400366004611a92565b611142565b60006301ffc9a760e01b6001600160e01b03198316148061043657506380ac58cd60e01b6001600160e01b03198316145b806104515750635b5e139f60e01b6001600160e01b03198316145b8061046c575063780e9d6360e01b6001600160e01b03198316145b8061048757506307f5828d60e41b6001600160e01b03198316145b806104a257506391a6262f60e01b6001600160e01b03198316145b92915050565b600180546104b590611cc6565b80601f01602080910402602001604051908101604052809291908181526020018280546104e190611cc6565b801561052e5780601f106105035761010080835404028352916020019161052e565b820191906000526020600020905b81548152906001019060200180831161051157829003601f168201915b505050505081565b60405163072b78c760e01b815260040160405180910390fd5b600754604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd9160048083019260209291908290030181865afa158015610599573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105bd9190611d00565b905090565b60005b81518110156106b25760008282815181106105e2576105e2611d19565b60209081029190910101516007546040516331a9108f60e11b81526004810183905291925082916001600160a01b0390911690636352211e90602401602060405180830381865afa15801561063b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065f9190611d2f565b6001600160a01b031660006001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a450806106aa81611d62565b9150506105c5565b5050565b6040516001600160e01b031960e083901b16815265ffffffffffff8416600482015260609083908390602401600060405180830381865afa92505050801561072057506040513d6000823e601f3d908101601f1916820160405261071d9190810190611d7b565b60015b61074b57846040516020016107359190611de8565b6040516020818303038152906040529050610771565b858160405160200161075e929190611e3e565b6040516020818303038152906040529150505b949350505050565b60058054819061078890611cc6565b80601f01602080910402602001604051908101604052809291908181526020018280546107b490611cc6565b80156108015780601f106107d657610100808354040283529160200191610801565b820191906000526020600020905b8154815290600101906020018083116107e457829003601f168201915b5050506001909301549192505065ffffffffffff80821691600160301b8104821691600160601b8204811691600160901b8104821691600160c01b9091041686565b60065460609065ffffffffffff908116908316106108835760405161086d90600590602001611f22565b6040516020818303038152906040529050919050565b600561089665ffffffffffff84166111b7565b60405160200161086d929190611f6c565b600754604051632f745c5960e01b81526001600160a01b038481166004830152602482018490526000921690632f745c5990604401602060405180830381865afa1580156108f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061091d9190611d00565b9392505050565b6007546040516301e0a07d60e71b815260048101839052606091829160009182918291829182916001600160a01b03169063f0503e809060240160a060405180830381865afa15801561097b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061099f9190611fcb565b945094509450945094506000600760009054906101000a90046001600160a01b03166001600160a01b031663303e74df6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109fe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a229190611d2f565b90506000816001600160a01b0316632065ce0b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a889190611d2f565b9050610a9330611249565b610a9c8b6111b7565b610aa589610843565b604080518082019091526004815263424f445960e01b6020820152600654610ade91908b90600160301b900465ffffffffffff16610cfa565b6040805180820190915260098152684143434553534f525960b81b6020820152600654610b1c91908b90600160601b900465ffffffffffff16610cfa565b604080518082019091526005815264484541445360d81b6020820152600654610b5691908b90600160901b900465ffffffffffff16610cfa565b6040805180820190915260078152664e4f47474c455360c81b6020820152600654610b9291908b90600160c01b900465ffffffffffff16610cfa565b604051602001610ba89796959493929190612040565b60408051601f19818403018152828201909152600a825269109858dad9dc9bdd5b9960b21b60208301529850610bed90886001600160a01b0384166304bde4dd6106b6565b610c2260405180604001604052806004815260200163426f647960e01b81525088846001600160a01b03166344cee73c6106b6565b610c5c604051806040016040528060098152602001684163636573736f727960b81b81525088856001600160a01b0316637ca942106106b6565b610c91604051806040016040528060048152602001631219585960e21b81525088866001600160a01b0316635a503f136106b6565b610cc960405180604001604052806007815260200166476c617373657360c81b81525088876001600160a01b031663b982d1b96106b6565b604051602001610cdd959493929190612110565b604051602081830303815290604052985050505050505050915091565b60608165ffffffffffff168365ffffffffffff1610610d3d57604051610d279060059086906020016121a6565b604051602081830303815290604052905061091d565b600584610d5165ffffffffffff86166111b7565b604051602001610d6393929190612203565b60405160208183030381529060405290509392505050565b600754604051634f6ccce760e01b8152600481018390526000916001600160a01b031690634f6ccce7906024015b602060405180830381865afa158015610dc6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104a29190611d00565b6007546040516331a9108f60e11b8152600481018390526000916001600160a01b031690636352211e90602401602060405180830381865afa158015610e34573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104a29190611d2f565b6007546040516370a0823160e01b81526001600160a01b03838116600483015260009216906370a0823190602401610da9565b600280546104b590611cc6565b6000546001600160a01b03163314610ecb5760405162461bcd60e51b8152600401610ec290612274565b60405180910390fd5b60036106b282826122e9565b6000546001600160a01b03163314610f015760405162461bcd60e51b8152600401610ec290612274565b805181906005908190610f1490826122e9565b5060208201516001909101805460408401516060850151608086015160a09096015165ffffffffffff908116600160c01b0265ffffffffffff60c01b19978216600160901b0265ffffffffffff60901b19938316600160601b02939093166bffffffffffffffffffffffff60601b19948316600160301b026bffffffffffffffffffffffff199096169290971691909117939093179190911693909317929092179290921617905550565b600380546104b590611cc6565b6007546040516331a9108f60e11b8152600481018390526060916000916001600160a01b0390911690636352211e90602401602060405180830381865afa15801561101b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061103f9190611d2f565b6001600160a01b0316036110695760405163c927e5bf60e01b815260048101839052602401610ec2565b60008061107584610924565b915091506110d7611085856111b7565b61108e866111b7565b846003856040516020016110a39291906123a8565b60408051601f19818403018152908290526110c3949392916020016123cd565b60405160208183030381529060405261125f565b6040516020016110e791906124d6565b60405160208183030381529060405292505050919050565b6000546001600160a01b031633146111295760405162461bcd60e51b8152600401610ec290612274565b60046106b282826122e9565b600480546104b590611cc6565b6000546001600160a01b0316331461116c5760405162461bcd60e51b8152600401610ec290612274565b600080546001600160a01b0319166001600160a01b0383169081178255604051909133917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a350565b606060006111c4836113c3565b60010190506000816001600160401b038111156111e3576111e3611707565b6040519080825280601f01601f19166020018201604052801561120d576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461121757509392505050565b60606104a26001600160a01b038316601461149b565b6060815160000361127e57505060408051602081019091526000815290565b600060405180606001604052806040815260200161257f60409139905060006003845160026112ad919061251b565b6112b7919061252e565b6112c2906004612550565b905060006112d182602061251b565b6001600160401b038111156112e8576112e8611707565b6040519080825280601f01601f191660200182016040528015611312576020820181803683370190505b509050818152600183018586518101602084015b8183101561137e576003830192508251603f8160121c168501518253600182019150603f81600c1c168501518253600182019150603f8160061c168501518253600182019150603f8116850151825350600101611326565b60038951066001811461139857600281146113a9576113b5565b613d3d60f01b6001198301526113b5565b603d60f81b6000198301525b509398975050505050505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106114025772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef8100000000831061142e576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061144c57662386f26fc10000830492506010015b6305f5e1008310611464576305f5e100830492506008015b612710831061147857612710830492506004015b6064831061148a576064830492506002015b600a83106104a25760010192915050565b606060006114aa836002612550565b6114b590600261251b565b6001600160401b038111156114cc576114cc611707565b6040519080825280601f01601f1916602001820160405280156114f6576020820181803683370190505b509050600360fc1b8160008151811061151157611511611d19565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061154057611540611d19565b60200101906001600160f81b031916908160001a9053506000611564846002612550565b61156f90600161251b565b90505b60018111156115e7576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106115a3576115a3611d19565b1a60f81b8282815181106115b9576115b9611d19565b60200101906001600160f81b031916908160001a90535060049490941c936115e081612567565b9050611572565b50831561091d5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610ec2565b60006020828403121561164857600080fd5b81356001600160e01b03198116811461091d57600080fd5b60005b8381101561167b578181015183820152602001611663565b50506000910152565b6000815180845261169c816020860160208601611660565b601f01601f19169290920160200192915050565b60208152600061091d6020830184611684565b6001600160a01b03811681146116d857600080fd5b50565b600080604083850312156116ee57600080fd5b82356116f9816116c3565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b038111828210171561173f5761173f611707565b60405290565b604051601f8201601f191681016001600160401b038111828210171561176d5761176d611707565b604052919050565b6000602080838503121561178857600080fd5b82356001600160401b038082111561179f57600080fd5b818501915085601f8301126117b357600080fd5b8135818111156117c5576117c5611707565b8060051b91506117d6848301611745565b81815291830184019184810190888411156117f057600080fd5b938501935b8385101561180e578435825293850193908501906117f5565b98975050505050505050565b60006001600160401b0382111561183357611833611707565b50601f01601f191660200190565b600082601f83011261185257600080fd5b81356118656118608261181a565b611745565b81815284602083860101111561187a57600080fd5b816020850160208301376000918101602001919091529392505050565b65ffffffffffff811681146116d857600080fd5b80356118b681611897565b919050565b600080600080606085870312156118d157600080fd5b84356001600160401b038111156118e757600080fd5b6118f387828801611841565b945050602085013561190481611897565b9250604085013567ffffffffffffffff198116811461192257600080fd5b8060601c925063ffffffff8160401c1691505092959194509250565b60008060006060848603121561195357600080fd5b833561195e816116c3565b9250602084013561196e816116c3565b929592945050506040919091013590565b60c08152600061199260c0830189611684565b65ffffffffffff97881660208401529587166040830152509285166060840152908416608083015290921660a090920191909152919050565b6000602082840312156119dd57600080fd5b813561091d81611897565b6000602082840312156119fa57600080fd5b5035919050565b604081526000611a146040830185611684565b8281036020840152611a268185611684565b95945050505050565b600080600060608486031215611a4457600080fd5b83356001600160401b03811115611a5a57600080fd5b611a6686828701611841565b9350506020840135611a7781611897565b91506040840135611a8781611897565b809150509250925092565b600060208284031215611aa457600080fd5b813561091d816116c3565b600080600060608486031215611ac457600080fd5b833592506020840135611ad6816116c3565b91506040840135611a87816116c3565b600060208284031215611af857600080fd5b81356001600160401b03811115611b0e57600080fd5b61077184828501611841565b60008060408385031215611b2d57600080fd5b8235611b38816116c3565b915060208301358015158114611b4d57600080fd5b809150509250929050565b600060208284031215611b6a57600080fd5b81356001600160401b0380821115611b8157600080fd5b9083019060c08286031215611b9557600080fd5b611b9d61171d565b823582811115611bac57600080fd5b611bb887828601611841565b82525060208301359150611bcb82611897565b81602082015260408301359150611be182611897565b81604082015260608301359150611bf782611897565b816060820152611c09608084016118ab565b6080820152611c1a60a084016118ab565b60a082015295945050505050565b600080600080600060808688031215611c4057600080fd5b8535611c4b816116c3565b94506020860135611c5b816116c3565b93506040860135925060608601356001600160401b0380821115611c7e57600080fd5b818801915088601f830112611c9257600080fd5b813581811115611ca157600080fd5b896020828501011115611cb357600080fd5b9699959850939650602001949392505050565b600181811c90821680611cda57607f821691505b602082108103611cfa57634e487b7160e01b600052602260045260246000fd5b50919050565b600060208284031215611d1257600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b600060208284031215611d4157600080fd5b815161091d816116c3565b634e487b7160e01b600052601160045260246000fd5b600060018201611d7457611d74611d4c565b5060010190565b600060208284031215611d8d57600080fd5b81516001600160401b03811115611da357600080fd5b8201601f81018413611db457600080fd5b8051611dc26118608261181a565b818152856020838501011115611dd757600080fd5b611a26826020830160208601611660565b6e3d913a3930b4ba2fba3cb832911d1160891b81528151600090611e1381600f850160208701611660565b73222c2276616c7565223a22556e6b6e6f776e227d60601b600f939091019283015250602301919050565b6e3d913a3930b4ba2fba3cb832911d1160891b81528251600090611e6981600f850160208801611660565b6a1116113b30b63ab2911d1160a91b600f918401918201528351611e9481601a840160208801611660565b61227d60f01b601a9290910191820152601c01949350505050565b60008154611ebc81611cc6565b60018281168015611ed45760018114611ee957611f18565b60ff1984168752821515830287019450611f18565b8560005260208060002060005b85811015611f0f5781548a820152908401908201611ef6565b50505082870194505b5050505092915050565b6726696d616765733d60c01b81526000611f3f6008830184611eaf565b7f2f4241434b47524f554e442f46414c4c4241434b2e504e47000000000000000081526018019392505050565b6726696d616765733d60c01b81526000611f896008830185611eaf565b6b2f4241434b47524f554e442f60a01b81528351611fae81600c840160208801611660565b632e504e4760e01b600c9290910191820152601001949350505050565b600080600080600060a08688031215611fe357600080fd5b8551611fee81611897565b6020870151909550611fff81611897565b604087015190945061201081611897565b606087015190935061202181611897565b608087015190925061203281611897565b809150509295509295909350565b703f636f6e7472616374416464726573733d60781b815260008851602061206d8260118601838e01611660565b81840191506826746f6b656e49643d60b81b6011830152601a8a5161209781838601858f01611660565b8a519301926120ab81838601858e01611660565b89519301926120bf81838601858d01611660565b88519301926120d381838601858c01611660565b87519301926120e781838601858b01611660565b86519301926120fb81838601858a01611660565b929092019091019a9950505050505050505050565b60008651612122818460208b01611660565b8083019050600b60fa1b8082528751612142816001850160208c01611660565b60019201918201819052865161215f816002850160208b01611660565b60029201918201819052855161217c816003850160208a01611660565b60039201918201528351612197816004840160208801611660565b01600401979650505050505050565b6726696d616765733d60c01b815260006121c36008830185611eaf565b602f60f81b815283516121dd816001840160208801611660565b6c2f46414c4c4241434b2e504e4760981b60019290910191820152600e01949350505050565b6726696d616765733d60c01b815260006122206008830186611eaf565b602f60f81b808252855161223b816001850160208a01611660565b60019201918201528351612256816002840160208801611660565b632e504e4760e01b6002929091019182015260060195945050505050565b6020808252600c908201526b15539055551213d49256915160a21b604082015260600190565b601f8211156122e457600081815260208120601f850160051c810160208610156122c15750805b601f850160051c820191505b818110156122e0578281556001016122cd565b5050505b505050565b81516001600160401b0381111561230257612302611707565b612316816123108454611cc6565b8461229a565b602080601f83116001811461234b57600084156123335750858301515b600019600386901b1c1916600185901b1785556122e0565b600085815260208120601f198616915b8281101561237a5788860151825594840194600190910190840161235b565b50858210156123985787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006123b48285611eaf565b83516123c4818360208801611660565b01949350505050565b717b226e616d65223a22476e6172204844202360701b815284516000906123fb816012850160208a01611660565b7f222c20226465736372697074696f6e223a224869676820646566696e6974696f601291840191820152676e20476e6172202360c01b6032820152855161244981603a840160208a01611660565b6b0818dbdd5b9d195c9c185c9d60a21b603a929091019182015271222c202261747472696275746573223a205b60701b60468201528451612491816058840160208901611660565b6c2e96101134b6b0b3b2911d101160991b6058929091019182015283516124bf816065840160208801611660565b61180e60658284010161227d60f01b815260020190565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081526000825161250e81601d850160208701611660565b91909101601d0192915050565b808201808211156104a2576104a2611d4c565b60008261254b57634e487b7160e01b600052601260045260246000fd5b500490565b80820281158282048414176104a2576104a2611d4c565b60008161257657612576611d4c565b50600019019056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220b0a852002ace2edfe8b5a17b5dda48285d33a004ab58247d8ace1b0ea440fa8064736f6c63430008150033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000558bfff0d583416f7c4e380625c7865821b8e95c00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000240000000000000000000000000e43ffd378684568236d63728c60b492bc53700d5000000000000000000000000000000000000000000000000000000000000002968747470733a2f2f6170692e7a6f72612e636f2f72656e64657265722f737461636b2d696d61676573000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000009900000000000000000000000000000000000000000000000000000000000000eb00000000000000000000000000000000000000000000000000000000000000440000000000000000000000000000000000000000000000000000000000000042697066733a2f2f6261667962656962726b776b613772376b6a6f66766c61646c6b737770347a7a6b61626e336e686d6b65646b6c6274796c6e6a75676877326d36650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000042697066733a2f2f6261666b726569656c336d617070757a6c646236726f666b64777874356577707434336e72686c33797834756c70706e79373533733662616e6e61000000000000000000000000000000000000000000000000000000000000
-----Encoded View---------------
22 Constructor Arguments found :
Arg [0] : 000000000000000000000000558bfff0d583416f7c4e380625c7865821b8e95c
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000240
Arg [4] : 000000000000000000000000e43ffd378684568236d63728c60b492bc53700d5
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000029
Arg [6] : 68747470733a2f2f6170692e7a6f72612e636f2f72656e64657265722f737461
Arg [7] : 636b2d696d616765730000000000000000000000000000000000000000000000
Arg [8] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [9] : 000000000000000000000000000000000000000000000000000000000000000c
Arg [10] : 000000000000000000000000000000000000000000000000000000000000001e
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000099
Arg [12] : 00000000000000000000000000000000000000000000000000000000000000eb
Arg [13] : 0000000000000000000000000000000000000000000000000000000000000044
Arg [14] : 0000000000000000000000000000000000000000000000000000000000000042
Arg [15] : 697066733a2f2f6261667962656962726b776b613772376b6a6f66766c61646c
Arg [16] : 6b737770347a7a6b61626e336e686d6b65646b6c6274796c6e6a75676877326d
Arg [17] : 3665000000000000000000000000000000000000000000000000000000000000
Arg [18] : 0000000000000000000000000000000000000000000000000000000000000042
Arg [19] : 697066733a2f2f6261666b726569656c336d617070757a6c646236726f666b64
Arg [20] : 777874356577707434336e72686c33797834756c70706e79373533733662616e
Arg [21] : 6e61000000000000000000000000000000000000000000000000000000000000


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

OVERVIEW

High definition Gnars counterparts

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
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.