ETH Price: $2,647.96 (-1.05%)

Contract

0x75Cd3F538c091C1D514aB1aD9832f54198CAceC0
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
0x1eaec2db992506606dec8314eefb754d8ce99de7d9236fdfa39b9f2dda248b52 Assert Ownership(pending)2024-09-29 22:01:043 hrs ago1727647264IN
Gnars HD: GNARSHD Token
0 ETH(Pending)(Pending)
0xdcd9ab3f86bdfb281a31f3d1f3a830d1ccf308d02185e771449eff549f367092 Assert Ownership(pending)2024-09-29 6:41:4318 hrs ago1727592103IN
Gnars HD: GNARSHD Token
0 ETH(Pending)(Pending)
0x443e299e62249325a8c529d2120d501becc9d03f23c26df7d89b3c5c857f0b0b Assert Ownership(pending)2024-09-29 1:18:3123 hrs ago1727572711IN
Gnars HD: GNARSHD Token
0 ETH(Pending)(Pending)
0x4b8a4e95a3e8b9aa9de19334b7bc83fa6a65128642b3ad2e2237abe49af1c5c5 Assert Ownership(pending)2024-09-28 19:41:2429 hrs ago1727552484IN
Gnars HD: GNARSHD Token
0 ETH(Pending)(Pending)
0x06d2b4e1575bca758f9321c6891d51db5741935df5a47a04c50fcda734cbd76b Assert Ownership(pending)2024-09-28 17:00:1032 hrs ago1727542810IN
Gnars HD: GNARSHD Token
0 ETH(Pending)(Pending)
0x7bbda8fbd26c72b8fae452915e6cce770aabe566d862a8c0948dc5bccdcfa563 Assert Ownership(pending)2024-09-28 15:58:1333 hrs ago1727539093IN
Gnars HD: GNARSHD Token
0 ETH(Pending)(Pending)
0x588568ab797017b22b0f680c8cde3bd59170dbb7874794ce9450e9dab8604b78 Assert Ownership(pending)2024-09-28 14:22:0434 hrs ago1727533324IN
Gnars HD: GNARSHD Token
0 ETH(Pending)(Pending)
0x085e864de73a26f15effc8cd5e871171c07e7a1c4ab561b25da3797a6f22438f Assert Ownership(pending)2024-09-28 12:29:1436 hrs ago1727526554IN
Gnars HD: GNARSHD Token
0 ETH(Pending)(Pending)
Assert Ownership208599112024-09-30 0:34:2336 mins ago1727656463IN
Gnars HD: GNARSHD Token
0 ETH0.000219136.8260973
Assert Ownership208580402024-09-29 18:18:116 hrs ago1727633891IN
Gnars HD: GNARSHD Token
0 ETH0.000253567.89886567
Assert Ownership208561202024-09-29 11:52:5913 hrs ago1727610779IN
Gnars HD: GNARSHD Token
0 ETH0.000189315.8973634
Assert Ownership208560432024-09-29 11:37:3513 hrs ago1727609855IN
Gnars HD: GNARSHD Token
0 ETH0.000186785.81836271
Assert Ownership208558972024-09-29 11:08:1114 hrs ago1727608091IN
Gnars HD: GNARSHD Token
0 ETH0.000184995.76274921
Assert Ownership208557222024-09-29 10:33:1114 hrs ago1727605991IN
Gnars HD: GNARSHD Token
0 ETH0.000217166.76488202
Assert Ownership208556952024-09-29 10:27:4714 hrs ago1727605667IN
Gnars HD: GNARSHD Token
0 ETH0.00023267.24590868
Assert Ownership208555702024-09-29 10:02:3515 hrs ago1727604155IN
Gnars HD: GNARSHD Token
0 ETH0.000177325.5239091
Assert Ownership208554422024-09-29 9:36:5915 hrs ago1727602619IN
Gnars HD: GNARSHD Token
0 ETH0.000241027.50815738
Assert Ownership208546132024-09-29 6:50:3518 hrs ago1727592635IN
Gnars HD: GNARSHD Token
0 ETH0.000207126.45204005
Assert Ownership208543922024-09-29 6:05:3519 hrs ago1727589935IN
Gnars HD: GNARSHD Token
0 ETH0.000165135.14421455
Assert Ownership208543742024-09-29 6:01:5919 hrs ago1727589719IN
Gnars HD: GNARSHD Token
0 ETH0.000180445.62100632
Assert Ownership208540982024-09-29 5:06:3520 hrs ago1727586395IN
Gnars HD: GNARSHD Token
0 ETH0.000168495.2485981
Assert Ownership208540632024-09-29 4:59:2320 hrs ago1727585963IN
Gnars HD: GNARSHD Token
0 ETH0.000162175.05193456
Assert Ownership208540512024-09-29 4:56:5920 hrs ago1727585819IN
Gnars HD: GNARSHD Token
0 ETH0.000160424.99747338
Assert Ownership208539132024-09-29 4:29:2320 hrs ago1727584163IN
Gnars HD: GNARSHD Token
0 ETH0.000177775.53779326
Assert Ownership208538862024-09-29 4:23:5920 hrs ago1727583839IN
Gnars HD: GNARSHD Token
0 ETH0.000176435.4959512
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
208599112024-09-30 0:34:2336 mins ago1727656463
0x75Cd3F53...198CAceC0
0 ETH
208580402024-09-29 18:18:116 hrs ago1727633891
0x75Cd3F53...198CAceC0
0 ETH
208561202024-09-29 11:52:5913 hrs ago1727610779
0x75Cd3F53...198CAceC0
0 ETH
208560432024-09-29 11:37:3513 hrs ago1727609855
0x75Cd3F53...198CAceC0
0 ETH
208558972024-09-29 11:08:1114 hrs ago1727608091
0x75Cd3F53...198CAceC0
0 ETH
208557222024-09-29 10:33:1114 hrs ago1727605991
0x75Cd3F53...198CAceC0
0 ETH
208556952024-09-29 10:27:4714 hrs ago1727605667
0x75Cd3F53...198CAceC0
0 ETH
208555702024-09-29 10:02:3515 hrs ago1727604155
0x75Cd3F53...198CAceC0
0 ETH
208554422024-09-29 9:36:5915 hrs ago1727602619
0x75Cd3F53...198CAceC0
0 ETH
208546132024-09-29 6:50:3518 hrs ago1727592635
0x75Cd3F53...198CAceC0
0 ETH
208543922024-09-29 6:05:3519 hrs ago1727589935
0x75Cd3F53...198CAceC0
0 ETH
208543742024-09-29 6:01:5919 hrs ago1727589719
0x75Cd3F53...198CAceC0
0 ETH
208540982024-09-29 5:06:3520 hrs ago1727586395
0x75Cd3F53...198CAceC0
0 ETH
208540632024-09-29 4:59:2320 hrs ago1727585963
0x75Cd3F53...198CAceC0
0 ETH
208540512024-09-29 4:56:5920 hrs ago1727585819
0x75Cd3F53...198CAceC0
0 ETH
208539132024-09-29 4:29:2320 hrs ago1727584163
0x75Cd3F53...198CAceC0
0 ETH
208538862024-09-29 4:23:5920 hrs ago1727583839
0x75Cd3F53...198CAceC0
0 ETH
208536972024-09-29 3:46:1121 hrs ago1727581571
0x75Cd3F53...198CAceC0
0 ETH
208535752024-09-29 3:21:4721 hrs ago1727580107
0x75Cd3F53...198CAceC0
0 ETH
208529872024-09-29 1:23:1123 hrs ago1727572991
0x75Cd3F53...198CAceC0
0 ETH
208407602024-09-27 8:27:232 days ago1727425643
0x75Cd3F53...198CAceC0
0 ETH
208337242024-09-26 8:54:473 days ago1727340887
0x75Cd3F53...198CAceC0
0 ETH
207849442024-09-19 13:29:3510 days ago1726752575
0x75Cd3F53...198CAceC0
0 ETH
207784852024-09-18 15:50:4711 days ago1726674647
0x75Cd3F53...198CAceC0
0 ETH
207717472024-09-17 17:14:1112 days ago1726593251
0x75Cd3F53...198CAceC0
0 ETH
View All Internal Transactions
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.