Contract 0x4E1824ca2E3dcef21D8eABcF11cCD2B5Fd46774B 2

 
 
Txn Hash
Method
Block
From
To
Value
0x70ca08364944cf9a157b5fd55eed9b03e10eb64ff1e7d678c7a061e76973e396Safe Transfer Fr...161315542022-12-07 8:08:351 hr 49 mins agoENS Name 02709.eth IN  0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774b0 Ether0.00105601 14.11392685
0x1fee3e44c8985690795d60f8497142f1b6791d77aa83aa8d8d3af8a6ef55ed13Safe Transfer Fr...161315462022-12-07 8:06:351 hr 51 mins agoENS Name 02709.eth IN  0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774b0 Ether0.00074507 14.20306037
0x4584f48b1e85d1a09ebc1c1dbd82c48652c4263fb5a8f76d4c757ea2dfd37a55Safe Transfer Fr...161315402022-12-07 8:05:231 hr 53 mins agoENS Name 02709.eth IN  0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774b0 Ether0.00159415 14.02389202
0x497f128bf0b049523fb1308ad758f2bf6418494121c110cffa391a0ab9f97deeSafe Transfer Fr...161315222022-12-07 8:01:231 hr 57 mins ago0x32b40c8279504bae1f7c0e69a86395bf33d83a5f IN  0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774b0 Ether0.00074497 15.63128351
0x4ad0ab9739890c82126b65c8fd0292908aeb474a42520030f49109bab5db0167Safe Transfer Fr...161315062022-12-07 7:58:112 hrs agoENS Name 02709.eth IN  0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774b0 Ether0.00163207 15.2801878
0x1b13b75de65f57eb5119b7f2edab760fb0721ae59b3fc6224a4517f6e4b7a29bWithdraw161313522022-12-07 7:26:112 hrs 32 mins agoChain Runners: Deployer IN  0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774b0 Ether0.0004560115
0xbc45e94c6ce0b753eac2a0a9dde35e879ba760c90a37ed7df40db8b72de93434Set Approval For...161308952022-12-07 5:51:474 hrs 6 mins ago0x70f3aad039c5a030bd71f16201d24c68ddfc21ba IN  0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774b0 Ether0.00066383 14.3174966
0x40fc9a7b880f8e20d538d514776d1cb5d424355570a9cb91fece9b661df13117Set Approval For...161305592022-12-07 4:41:235 hrs 17 mins ago0xfc9d508d75fc6683ec2ac639471d8a2df6ff6126 IN  0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774b0 Ether0.0006203613.38
0x6ce789acbf7f71ce1b6d54095f0b71cf00f1bd95e062edcb3f07a679920f6eefSet Approval For...161298442022-12-07 2:12:237 hrs 46 mins ago0x4d8f60eb269eb4f9d540dd9685391b4c8bd18260 IN  0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774b0 Ether0.00066325 14.29760895
0xf0be7983d94e4fe70c97daf152d625a4ae16798768b05e9eaf9bc9d8581d4c9aSafe Transfer Fr...161291892022-12-06 23:58:599 hrs 59 mins ago0x6a21ceff0e4f0f344f8c9850d9658ac0247e9883 IN  0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774b0 Ether0.00091378 13.95992411
0x4cef645c78c5c7d85ddc648fccbd155eacb5d945cb593739d312287b148336a8Safe Transfer Fr...161275552022-12-06 18:30:2315 hrs 28 mins ago0xfe505fdc65030dd93f44c5bae1b0f36a55b50291 IN  0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774b0 Ether0.00123159 25.57985221
0x716e1dd706731c927d89c8dcbcd2c655339277635d8dc53448520e5ea870debcClaim All161263302022-12-06 14:24:1119 hrs 34 mins agoENS Name poopshakes.eth IN  0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774b0 Ether0.00651415 21.13789883
0x92127fe614faa8377ff8861811f721918041afbe5d5ace40503b51b8503ff8a5Set Approval For...161226242022-12-06 2:00:231 day 7 hrs agoENS Name oyakodon.eth IN  0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774b0 Ether0.00060458 13.03293158
0x167cc3ee18ebe8d72ae7202525ae263143e67c0ef20c9576a7ef5813bd6b00f5Set Approval For...161226132022-12-06 1:58:111 day 8 hrs agoENS Name oyakodon.eth IN  0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774b0 Ether0.00057334 12.36596498
0x8fa7c9660e6c25b79c6d49fe631435fdcd6b5ed8dde0a2b764193c976bb559c5Set Approval For...161215732022-12-05 22:29:111 day 11 hrs ago0x6a21ceff0e4f0f344f8c9850d9658ac0247e9883 IN  0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774b0 Ether0.00064839 13.97743831
0x9cb3c1f7730780441938307b9857b64af630b51d979d9b8c15e7b0099423ee5cSet Approval For...161205862022-12-05 19:10:591 day 14 hrs agoENS Name 0x0nft.eth IN  0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774b0 Ether0.000827 17.82765183
0x91eba568f0716459e1c79f1a4602263fa6209d56b484bd1d295f1ebf13a3365aSet Approval For...161205582022-12-05 19:05:231 day 14 hrs agoENS Name bestinvestor.eth IN  0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774b0 Ether0.00081772 17.62752477
0xb72c740815fdeedf90e4ae135f147278203d9443c7991166d76f35cdd3942ad5Claim All161204872022-12-05 18:50:591 day 15 hrs ago0xabf9fc4cdea39d11ff82d33b018264ef56726772 IN  0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774b0 Ether0.00046714 14.61842904
0xda8aed793e1ae669c67145a6ffa3f8a7dcad25e1305de47a5e78e5713b86aa04Claim All161204822022-12-05 18:49:591 day 15 hrs ago0xabf9fc4cdea39d11ff82d33b018264ef56726772 IN  0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774b0 Ether0.00046104 14.42760097
0x45b04eb45f929a1c1321b818230818dcf38b98dafdf2532e00a4daa2700410c3Claim All161204552022-12-05 18:44:351 day 15 hrs agoENS Name mikedore.eth IN  0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774b0 Ether0.00084069 16.28124161
0xeff16a75019fcc48f1cb72dd8c2a5562bb86c3bc7aa6a8df50f7665e77f2f214Claim All161204502022-12-05 18:43:351 day 15 hrs agoENS Name mikedore.eth IN  0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774b0 Ether0.00418534 18.21004652
0xf503309bf4936d56af4c27cef8ab518335e82c95b8fbedfef9e2826bbe9fd826Safe Transfer Fr...161203822022-12-05 18:29:591 day 15 hrs ago0x33fca372047d6866513c64c1e965b6ca0cc4b219 IN  0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774b0 Ether0.00080034 15.056041
0x08ee82c8b2f2c0a712c6b51a98cec2a1d8495bb52f175f8b2bb89d6dad59b4b8Safe Transfer Fr...161203692022-12-05 18:27:231 day 15 hrs ago0x33fca372047d6866513c64c1e965b6ca0cc4b219 IN  0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774b0 Ether0.00120571 17.16130912
0xc738860aea0031d1f8aa05b73e138ceb86937fc847704db3c2facc7a3b9b6494Set Approval For...161175272022-12-05 8:51:472 days 1 hr ago0x1b739c2ec70c8a40356effd1fc5302edd77c3a75 IN  0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774b0 Ether0.00056842 12.25976556
0xcf4c1659ccb22f34e77c57a11855159d8bcdb720dd0e5660ba2883e9097ad2f9Set Approval For...161175272022-12-05 8:51:472 days 1 hr ago0x1b739c2ec70c8a40356effd1fc5302edd77c3a75 IN  0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774b0 Ether0.00056871 12.25976556
[ Download CSV Export 
Latest 17 internal transactions
Parent Txn Hash Block From To Value
0x1b13b75de65f57eb5119b7f2edab760fb0721ae59b3fc6224a4517f6e4b7a29b161313522022-12-07 7:26:112 hrs 32 mins ago 0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774bChain Runners: Deployer0.3 Ether
0x18cfd8704d24e6c224bc49fac00d1bf5447c86d7206cb570f88dfc5bb29801f1159852102022-11-16 21:17:4720 days 12 hrs ago 0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774bChain Runners: Deployer12.5 Ether
0xe5091aeba6786805e5e220e66477c14265cd13f0cbe31a09fad43516437d122b151683502022-07-18 18:49:03141 days 15 hrs ago 0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774bChain Runners: Deployer9.4 Ether
0xcaf03b1f9e917d8869c2ee9f12c7a05a488d577a80d5974dd406c48c49c54ccb150982782022-07-07 23:12:28152 days 10 hrs ago 0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774bChain Runners: Deployer11.8 Ether
0xbaa05868c2402f3e23998ef4135094a5d32959bbf85fbb9e99ff64a409e782fd149643022022-06-14 22:54:27175 days 11 hrs ago 0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774bChain Runners: Deployer1.6 Ether
0xf1f4b84e5e4aee6e7caa0025d9ff6d788547e0091220fb0eb8e86172c959d46c149232802022-06-07 22:28:44182 days 11 hrs ago 0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774bChain Runners: Deployer28.6 Ether
0x9f5a5fce89013ddc5535d1a91b2ec72b2245132b9a38562154e4c2e813d16da7148463902022-05-26 6:08:25195 days 3 hrs ago 0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774bChain Runners: Deployer81.8 Ether
0x4a034a979745235c22c20e5084cb82ff4f834ad90a26996ba07604de13689519148275022022-05-23 4:34:02198 days 5 hrs ago 0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774bChain Runners: Deployer358.6 Ether
0xe3d7285f8a6b96e69ac4b7873309ad542fc8e3c339bcc2bdfb2a4fb802c3f0b6148180832022-05-21 15:43:17199 days 18 hrs ago 0x088227ee56b17e69c4e6865dc480d0a19d5156f4 0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774b0.1 Ether
0xf8da5158767a54aef423f5413e9e12aea69d0ed702eba2e63b7d9f41fd1025ac148175482022-05-21 13:35:25199 days 20 hrs ago 0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774bChain Runners: Deployer115.1 Ether
0x16492ebe3e181337732606ab8f7933d0d58e15c89901f76a7efb85a483185f42148174682022-05-21 13:18:03199 days 20 hrs ago 0x088227ee56b17e69c4e6865dc480d0a19d5156f4 0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774b0.1 Ether
0x05c896da860d3bf675215c1f6b62f64b38dc3a3ac907f7385835d0cbc64f99b8148174262022-05-21 13:07:05199 days 20 hrs ago 0x088227ee56b17e69c4e6865dc480d0a19d5156f4 0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774b0.1 Ether
0xe5b3593f4a9f51992c517803d65caaa31fa1432d2e59fcee39821f72fa7e21e0148138102022-05-20 22:59:52200 days 10 hrs ago 0xf5341baefbbcc4145ba581e092e9cf3af06a2e3e 0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774b0.1 Ether
0x117ad26dfeb73a93565d27bb53ff98fa9f304cfd5ce2529c10dc84abea0b2c58148131192022-05-20 20:21:45200 days 13 hrs ago 0xc5a6349aedf573ee01c7bdf3d713496b5a45d056 0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774b0.1 Ether
0xdc535935d76d49633bd4028a32b5d5b0236af9cc1c72572b738b5148f9a94be4148127192022-05-20 18:43:19200 days 15 hrs ago 0xf5341baefbbcc4145ba581e092e9cf3af06a2e3e 0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774b0.1 Ether
0x07fe08bc14d0fece5c34e7a0390e7099fa3063ea3f7ba8bade94d0203a28291b148126912022-05-20 18:36:18200 days 15 hrs ago 0xf5341baefbbcc4145ba581e092e9cf3af06a2e3e 0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774b0.1 Ether
0x6838451927009ea2725f71699a0f65e87c8707bd6a2eca47c5f39fe11449e51b148126702022-05-20 18:30:57200 days 15 hrs ago 0xf5341baefbbcc4145ba581e092e9cf3af06a2e3e 0x4e1824ca2e3dcef21d8eabcf11ccd2b5fd46774b0.1 Ether
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ChainRunnersXR

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 2000 runs

Other Settings:
default evmVersion
File 1 of 17 : ChainRunnersXR.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.4;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
import "./core/ERC721AClaimable.sol";
import "./interfaces/IChainRunnersRenderer.sol";
import "./interfaces/IChainRunners.sol";

/*
               ::::                                                                                                                                                  :::#%=
               @*==+-                                                                                                                                               ++==*=.
               #+=#=++..                                                                                                                                        ..=*=*+-#:
                :=+++++++=====================================:    .===============================================. .=========================================++++++++=
                 .%-+%##+=--==================================+=..=+-=============================================-+*+======================================---+##+=#-.
                   [email protected]@%[email protected]@@%+++++++++++++++++++++++++++%#++++++%#+++#@@@#[email protected]@%[email protected]#+.=+*@*+*@@@@*+++++++++++++++++++++++%@@@#+++#@@+++=
                    -*-#%@@%%%=*%@%*++=++=+==+=++=++=+=++=++==#@%#%#+++=+=*@%*+=+==+=+++%*[email protected]%%#%#++++*@%#++=++=++=++=+=++=++=+=+*%%*==*%@@@*:%=
                     :@:[email protected]@@@@@*+++%@@*+===========+*=========#@@========+#%==========*@========##*#*+=======*@##*======#@#+=======*#*============+#%++#@@%#@@#++=.
                      .*+=%@%*%@%##[email protected]@%#=-==-=--==*%=========*%==--=--=-====--=--=-=##=--=-=--%%%%%+=-=--=-=*%=--=--=-=#%=--=----=#%=--=-=--=-+%#+==#%@@*#%@=++.
                        +%.#@@###%@@@@@%*---------#@%########@%*---------------------##---------------------##---------%%*[email protected]@#---------+#@=#@@#[email protected]@%*++-
                        .:*+*%@#+=*%@@@*=-------=#%#=-------=%*---------=*#*--------#+=--------===--------=#%*-------=#%*[email protected]%#--------=%@@%#*+=-+#%*+*:.
       ====================%*[email protected]@%#==+##%@*[email protected]#[email protected]@*-------=*@[email protected]@*[email protected][email protected]=--------*@@+-------+#@@%#==---+#@.*%====================
     :*=--==================-:=#@@%*===+*@%+=============%%%@=========*%@*[email protected]+=--=====+%@[email protected][email protected]========*%@@+======%%%**+=---=%@#=:-====================-#-
       +++**%@@@#*****************@#*=---=##%@@@@@@@@@@@@@#**@@@@****************%@@*[email protected]#***********#@************************************+=------=*@#*********************@#+=+:
        .-##=*@@%*----------------+%@%=---===+%@@@@@@@*+++---%#++----------------=*@@*+++=-----------=+#=------------------------------------------+%+--------------------+#@[email protected]
         :%:#%#####+=-=-*@@+--=-==-=*@=--=-==-=*@@#*[email protected][email protected]%===-==----+-==-==--+*+-==-==---=*@@@@@@%#===-=-=+%@%-==-=-==-#@%=-==-==--+#@@@@@@@@@@@@*+++
        =*=#@#=----==-=-=++=--=-==-=*@=--=-==-=*@@[email protected]===-=--=-*@@*[email protected]=--=-==--+#@-==-==---+%-==-==---=+++#@@@#--==-=-=++++-=--=-===#%[email protected]@@%.#*
        +#:@%*===================++%#=========%@%=========#%=========+#@%+=======#%==========*@#=========*%=========+*+%@@@+========+*[email protected]@%+**+================*%#*=+=
       *++#@*+=++++++*#%*+++++=+++*%%++++=++++%%*=+++++++##*=++++=++=%@@++++=++=+#%++++=++++#%@=+++++++=*#*+++++++=#%@@@@@*++=++++=#%@*[email protected]#*****=+++++++=+++++*%@@+:=+=
    :=*=#%#@@@@#%@@@%#@@#++++++++++%%*+++++++++++++++++**@*+++++++++*%#++++++++=*##++++++++*%@%+++++++++##+++++++++#%%%%%%++++**#@@@@@**+++++++++++++++++=*%@@@%#@@@@#%@@@%#@++*:.
    #*:@#=-+%#+:=*@*[email protected]%#++++++++#%@@#*++++++++++++++#%@#*++++++++*@@#[email protected]#++++++++*@@#+++++++++##*+++++++++++++++++###@@@@++*@@#+++++++++++++++++++*@@#=:+#%[email protected]*=-+%*[email protected]=
    ++=#%#+%@@%=#%@%#+%%#++++++*#@@@%###**************@@@++++++++**#@##*********#*********#@@#++++++***@#******%@%#*++**#@@@%##+==+++=*#**********%%*++++++++#%#=%@@%+*%@%*+%#*=*-
     .-*+===========*@@+++++*%%%@@@++***************+.%%*++++#%%%@@%=:=******************[email protected]@#+++*%%@#==+***--*@%*++*%@@*===+**=--   -************[email protected]%%#++++++#@@@*==========*+-
        =*******##.#%#++++*%@@@%+==+=             *#-%@%**%%###*====**-               [email protected]:*@@##@###*==+**-.-#[email protected]@#*@##*==+***=                     =+=##%@*+++++*%@@#.#%******:
               ++++%#+++*#@@@@+++==.              **[email protected]@@%+++++++===-                 -+++#@@+++++++==:  :+++%@@+++++++==:                          [email protected]%##[email protected]@%++++
             :%:*%%****%@@%+==*-                .%==*====**+...                      #*.#+==***....    #+=#%+==****:.                                ..-*=*%@%#++*#%@=+%.
            -+++#%+#%@@@#++===                  [email protected]*++===-                            #%++===           %#+++===                                          =+++%@%##**@@*[email protected]:
          .%-=%@##@@%*==++                                                                                                                                 .*==+#@@%*%@%=*=.
         .+++#@@@@@*++==.                                                                                                                                    -==++#@@@@@@=+%
       .=*=%@@%%%#=*=.                                                                                                                                          .*+=%@@@@%+-#.
       @[email protected]@@%:++++.                                                                                                                                              -+++**@@#+*=:
    .-+=*#%%++*::.                                                                                                                                                  :+**=#%@#==#
    #*:@*+++=:                                                                                                                                                          [email protected]*++=:
  :*-=*=++..                                                                                                                                                             .=*=#*.%=
 +#.=+++:                                                                                                                                                                   ++++:+#
*+=#-::                                                                                                                                                                      .::*+=*

*/

contract ChainRunnersXR is Ownable, ERC721AClaimable, ReentrancyGuard {

    address public genesisContractAddress;
    address public xrRendererContractAddress;

    uint256 public immutable amountForDevs;
    uint256 public immutable mintCollectionSize;

    uint256 public numAvailableTokens = 10000;
    mapping(uint => uint) private _availableTokens;

    mapping(uint256 => uint256) tokenIdToContentIdMapping;

    uint256 public publicSaleStartTimestamp;
    uint256 public allowlistStartTimestamp;
    uint256 public claimStartTimestamp;

    mapping(address => uint256) public allowlist;
    bytes32 private allowlistMerkleRoot;

    uint256[40] claimedBitMap;

    uint256 public constant MAX_PER_ADDRESS_DURING_ALLOWLIST_MINT = 1;
    uint256 public constant MAX_PER_TRANSACTION_DURING_PUBLIC = 5;
    uint256 public constant PRICE_PER_TOKEN = 0.1 ether;
    uint256 public constant MAX_BATCH_SIZE = 5;

    uint256 revealSeed;

    uint256 public burningStartTimestamp;

    constructor(
        uint256 mintCollectionSize_,
        uint256 amountForDevs_,
        address genesisContractAddress_,
        address xrRendererContractAddress_
    ) ERC721AClaimable("Chain Runners XR", "XR") {
        mintCollectionSize = mintCollectionSize_;
        amountForDevs = amountForDevs_;
        genesisContractAddress = genesisContractAddress_;
        xrRendererContractAddress = xrRendererContractAddress_;
    }

    modifier callerIsUser() {
        require(tx.origin == msg.sender, "the caller is another contract");
        _;
    }

    // SALE CONFIG FUNCTIONS
    function setAllowlistSaleStartTimestamp(uint256 _allowlistStartTimestamp) external onlyOwner {
        allowlistStartTimestamp = _allowlistStartTimestamp;
    }

    function setPublicSaleStartTimestamp(uint256 _publicSaleStartTimestamp) external onlyOwner {
        publicSaleStartTimestamp = _publicSaleStartTimestamp;
    }

    function setClaimStartTimestamp(uint256 _claimStartTimestamp) external onlyOwner {
        claimStartTimestamp = _claimStartTimestamp;
    }

    function isPublicSaleActive() public view returns (bool) {
        return
        publicSaleStartTimestamp != 0 &&
        block.timestamp >= publicSaleStartTimestamp;
    }

    function isAllowlistSaleActive() public view returns (bool) {
        return
        allowlistStartTimestamp != 0 &&
        block.timestamp >= allowlistStartTimestamp;
    }

    function isClaimActive() public view returns (bool) {
        return
        claimStartTimestamp != 0 &&
        block.timestamp >= claimStartTimestamp;
    }

    function setAllowlistMerkleRoot(bytes32 _root) external onlyOwner {
        allowlistMerkleRoot = _root;
    }

    function setXRRenderingContractAddress(address _xrRenderingContractAddress) public onlyOwner {
        xrRendererContractAddress = _xrRenderingContractAddress;
    }

    function reveal(uint256 _revealSeed) external onlyOwner {
        revealSeed = _revealSeed;
    }

    // MINTING FUNCTIONS
    function mintDev(uint256 _quantity) external onlyOwner {
        require(
            _totalMinted() + _quantity <= mintCollectionSize,
            "too many already minted before dev mint"
        );
        require(
            _quantity % MAX_BATCH_SIZE == 0,
            "can only mint a multiple of the maxBatchSize"
        );
        require(_quantity <= amountForDevs, "quantity is too high");

        uint256 numChunks = _quantity / MAX_BATCH_SIZE;
        for (uint256 i = 0; i < numChunks; i++) {
            _mintRandom(msg.sender, MAX_BATCH_SIZE);
        }
    }

    function mintAllowlist(uint256 _quantity, bytes32[] calldata _merkleProof) external payable callerIsUser returns (uint256) {
        require(isAllowlistSaleActive(), "allowlist sale has not begun yet");
        require(MerkleProof.verify(_merkleProof, allowlistMerkleRoot, keccak256(abi.encodePacked(msg.sender))), "not on allowlist");
        require(allowlist[msg.sender] + _quantity <= MAX_PER_ADDRESS_DURING_ALLOWLIST_MINT, "not eligible for allowlist mint");
        require(_totalMinted() + _quantity <= (mintCollectionSize - amountForDevs), "reached max supply");

        uint256 totalCost = uint256(PRICE_PER_TOKEN * _quantity);
        unchecked {
            allowlist[msg.sender] += _quantity;
        }
        _mintRandom(msg.sender, _quantity);
        refundIfOver(totalCost);
        return _currentMintIndex - _quantity;
    }

    function mintPublic(uint256 _quantity) external payable callerIsUser returns (uint256) {
        require(isPublicSaleActive(), "public sale has not begun yet");
        require(_totalMinted() + _quantity <= (mintCollectionSize - amountForDevs), "reached max supply");
        require(_quantity <= MAX_PER_TRANSACTION_DURING_PUBLIC, "quantity too high");

        _mintRandom(msg.sender, _quantity);
        refundIfOver(PRICE_PER_TOKEN * _quantity);
        return _currentMintIndex - _quantity;
    }

    /**
    * Mint `_numToMint` tokens. Use Fisher Yates to draw a uniformly random
    * contentId to associate with each tokenId.
    */
    function _mintRandom(address _to, uint _numToMint) internal {
        uint updatedNumAvailableTokens = numAvailableTokens;
        for (uint256 i; i < _numToMint; i++) {
            uint256 contentId = getRandomAvailableContentId(_to, updatedNumAvailableTokens--);
            tokenIdToContentIdMapping[_currentMintIndex+i] = contentId;
        }
        _safeMint(_to, _numToMint);
        numAvailableTokens = updatedNumAvailableTokens;
    }

    function getRandomAvailableContentId(address _to, uint _updatedNumAvailableTokens)
    internal
    returns (uint256)
    {
        uint256 randomNum = randomNumber(_to, _updatedNumAvailableTokens);
        uint256 randomIndex = randomNum % _updatedNumAvailableTokens;
        return getAvailableTokenAtIndex(randomIndex, _updatedNumAvailableTokens);
    }

    function randomNumber(address _to, uint _updatedNumAvailableTokens) internal view returns (uint256) {
        return uint256(
            keccak256(
                abi.encode(
                    _to,
                    tx.gasprice,
                    block.number,
                    block.timestamp,
                    block.difficulty,
                    blockhash(block.number - 1),
                    address(this),
                    _updatedNumAvailableTokens
                )
            )
        );
    }

    // Implements https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle.  Code from https://github.com/erc721r/ERC721R/blob/main/contracts/ERC721R.sol
    function getAvailableTokenAtIndex(uint256 _indexToUse, uint _updatedNumAvailableTokens)
    internal
    returns (uint256)
    {
        uint256 valAtIndex = _availableTokens[_indexToUse];
        uint256 result;
        if (valAtIndex == 0) {
            // This means the index itself is still an available token
            result = _indexToUse;
        } else {
            // This means the index itself is not an available token, but the val at that index is.
            result = valAtIndex;
        }

        uint256 lastIndex = _updatedNumAvailableTokens - 1;
        if (_indexToUse != lastIndex) {
            // Replace the value at indexToUse, now that it's been used.
            // Replace it with the data from the last index in the array, since we are going to decrease the array size afterwards.
            uint256 lastValInArray = _availableTokens[lastIndex];
            if (lastValInArray == 0) {
                // This means the index itself is still an available token
                _availableTokens[_indexToUse] = lastIndex;
            } else {
                // This means the index itself is not an available token, but the val at that index is.
                _availableTokens[_indexToUse] = lastValInArray;
                // Gas refund courtesy of @dievardump
                delete _availableTokens[lastIndex];
            }
        }

        return result;
    }

    // CLAIM FUNCTIONS
    struct ClaimData {
        address to;
        uint256 start;
        uint256 count;
    }

    /**
    * Claim all tokens for sender.
    */
    function claimAll() external {
        require(isClaimActive(), "claim is not active");
        address owner = _msgSender();
        IChainRunners genesisContract = IChainRunners(genesisContractAddress);
        uint256 balance = genesisContract.balanceOf(owner);
        ClaimData memory batch;
        unchecked {
            for (uint256 i; i < balance; i++) {
                uint256 tokenId = genesisContract.tokenOfOwnerByIndex(owner, i);
                if (!isClaimed(tokenId)) {
                    if (batch.start == 0) {
                        batch.to = owner;
                        batch.start = tokenId;
                        batch.count = 1;
                    } else if (((batch.start+batch.count) != tokenId) || (batch.count == MAX_BATCH_SIZE)) {
                        _claim(batch.to, batch.start, batch.count);
                        batch.start = tokenId;
                        batch.count = 1;
                    } else {
                        batch.count++;
                    }
                    if (i == balance - 1) {
                        // Claim last batch
                       _claim(batch.to, batch.start, batch.count);
                    }
                    _setClaimed(tokenId);
                }
            }
        }
    }

    function claimsRemaining(address owner) public view returns (uint256) {
        IChainRunners genesisContract = IChainRunners(genesisContractAddress);
        uint256 balance = genesisContract.balanceOf(owner);
        unchecked {
            uint256 _claimsRemaining;
            for (uint256 i; i < balance; i++) {
                uint256 tokenId = genesisContract.tokenOfOwnerByIndex(owner, i);
                if (!isClaimed(tokenId)) {
                    _claimsRemaining++;
                }
            }
            return _claimsRemaining;
        }
    }

    function isClaimed(uint256 _tokenId) public view returns (bool) {
        uint256 claimedWordIndex = _tokenId / 256;
        uint256 claimedBitIndex = _tokenId % 256;
        uint256 claimedWord = claimedBitMap[claimedWordIndex];
        uint256 mask = (1 << claimedBitIndex);
        return claimedWord & mask == mask;
    }

    function _setClaimed(uint256 _tokenId) internal {
        uint256 claimedWordIndex = _tokenId / 256;
        uint256 claimedBitIndex = _tokenId % 256;
        claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);
    }

    function refundIfOver(uint256 _price) private {
        require(msg.value >= _price, "Need to send more ETH.");
        if (msg.value > _price) {
            payable(msg.sender).transfer(msg.value - _price);
        }
    }

    // RENDERING FUNCTIONS
    function getDna(uint256 _tokenId) public view returns (uint256) {
        IChainRunners genesisContract = IChainRunners(genesisContractAddress);
        uint256 dna_;
        if (_tokenId <= mintCollectionSize) {
            dna_ = genesisContract.getDna(_tokenId);
        } else {
            uint256 contentId = tokenIdToContentIdMapping[_tokenId];
            dna_ = uint256(keccak256(abi.encodePacked(
                revealSeed + (contentId % mintCollectionSize)
            )));
        }
        return dna_;
    }

    function tokenURI(uint256 _tokenId) public view virtual override returns (string memory) {
        require(_exists(_tokenId), "ERC721Metadata: URI query for nonexistent token");
        if (xrRendererContractAddress == address(0) || revealSeed == 0) {
            return '';
        }
        IChainRunnersRenderer renderer = IChainRunnersRenderer(xrRendererContractAddress);
        ChainRunnersTypes.ChainRunner memory runner;
        runner.dna = getDna(_tokenId);
        return renderer.tokenURI(_tokenId, runner);
    }

    // MISC FUNCTIONS
    function withdraw() public onlyOwner {
        (bool succ,) = payable(msg.sender).call{value : address(this).balance}("");
        require(succ, "transfer failed");
    }

    function ownershipStartTimestamp(uint256 _tokenId) public view returns (uint256) {
        (TokenOwnership memory ownership, ) = _ownershipOf(_tokenId);
        return ownership.startTimestamp;
    }

    function burn(uint256 tokenId) external {
        require(isBurningActive(), "burning not active");
        _burn(tokenId, true);
    }

    function isBurningActive() public view returns (bool) {
        return
        burningStartTimestamp != 0 &&
        block.timestamp >= burningStartTimestamp;
    }

    function setBurningStartTimestamp(uint256 _timestamp) public {
        burningStartTimestamp = _timestamp;
    }
}

File 2 of 17 : Ownable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _setOwner(_msgSender());
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _setOwner(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _setOwner(newOwner);
    }

    function _setOwner(address newOwner) private {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 3 of 17 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

File 4 of 17 : MerkleProof.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev These functions deal with verification of Merkle Trees proofs.
 *
 * The proofs can be generated using the JavaScript library
 * https://github.com/miguelmota/merkletreejs[merkletreejs].
 * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
 *
 * See `test/utils/cryptography/MerkleProof.test.js` for some examples.
 */
library MerkleProof {
    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(
        bytes32[] memory proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        bytes32 computedHash = leaf;

        for (uint256 i = 0; i < proof.length; i++) {
            bytes32 proofElement = proof[i];

            if (computedHash <= proofElement) {
                // Hash(current computed hash + current element of the proof)
                computedHash = keccak256(abi.encodePacked(computedHash, proofElement));
            } else {
                // Hash(current element of the proof + current computed hash)
                computedHash = keccak256(abi.encodePacked(proofElement, computedHash));
            }
        }

        // Check if the computed hash (root) is equal to the provided root
        return computedHash == root;
    }
}

File 5 of 17 : ERC721AClaimable.sol
// SPDX-License-Identifier: MIT
// Creator: Chain Runners, based on ERC721A by Chiru Labs

pragma solidity ^0.8.4;

import '@openzeppelin/contracts/token/ERC721/IERC721.sol';
import '@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol';
import '@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol';
import '@openzeppelin/contracts/utils/Address.sol';
import '@openzeppelin/contracts/utils/Context.sol';
import '@openzeppelin/contracts/utils/Strings.sol';
import '@openzeppelin/contracts/utils/introspection/ERC165.sol';

error ApprovalCallerNotOwnerNorApproved();
error ApprovalQueryForNonexistentToken();
error ApproveToCaller();
error ApprovalToCurrentOwner();
error BalanceQueryForZeroAddress();
error MintToZeroAddress();
error MintZeroQuantity();
error OwnerQueryForNonexistentToken();
error TransferCallerNotOwnerNorApproved();
error TransferFromIncorrectOwner();
error TransferToNonERC721ReceiverImplementer();
error TransferToZeroAddress();
error URIQueryForNonexistentToken();

/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension. Built to optimize for lower gas during batch mints.
 *
 * This is a modification to the ERC721A contract that supports a non-sequential token claiming range from
 * _startClaimTokenId() to _startMintTokenId(), and a sequential minting range starting at _startMintTokenId().
 *
 * Assumes minted serials are sequentially minted starting at _startMintTokenId() (defaults to 10001, e.g. 10000, 10001, 10002, 10003..).
 *
 * Claimed tokens can be minted in any order between _startClaimTokenId() and _startMintTokenId() (defaults to 1, e.g. 1 to 10000)
 *
 * Assumes that an owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
 *
 * Assumes that the maximum token id cannot exceed 2**256 - 1 (max value of uint256).
 */
contract ERC721AClaimable is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Compiler will pack this into a single 256bit word.
    struct TokenOwnership {
        // The address of the owner.
        address addr;
        // Keeps track of the start time of ownership with minimal overhead for tokenomics.
        uint64 startTimestamp;
        // Whether the token has been burned.
        bool burned;
        // Keeps track of how many tokens (above) this ownership record covers.  Only set/useful for claims
        uint256 quantity;
    }

    // Compiler will pack this into a single 256bit word.
    struct AddressData {
        // Realistically, 2**64-1 is more than enough.
        uint64 balance;
        // Keeps track of mint count with minimal overhead for tokenomics.
        uint64 numberMinted;
        // Keeps track of burn count with minimal overhead for tokenomics.
        uint64 numberBurned;
        // For miscellaneous variable(s) pertaining to the address
        // (e.g. number of whitelist mint slots used).
        // If there are multiple variables, please pack them into a uint64.
        uint64 aux;
    }

    // The tokenId of the next token to be minted.
    uint256 internal _currentMintIndex;

    // The number of claimed tokens.
    uint256 internal _numClaimed;

    // Max batch size per mint
    uint256 internal _maxBatchSize;

    // The number of tokens burned.
    uint256 internal _burnCounter;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to ownership details
    // An empty struct value does not necessarily mean the token is unowned. See _ownershipOf implementation for details.
    mapping(uint256 => TokenOwnership) internal _ownerships;

    // Mapping owner address to address data
    mapping(address => AddressData) private _addressData;

    // Mapping from token ID to approved address
    mapping(uint256 => address) private _tokenApprovals;

    // Mapping from owner to operator approvals
    mapping(address => mapping(address => bool)) private _operatorApprovals;

    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;

        _currentMintIndex = _startMintTokenId();

        _maxBatchSize = 5;
    }

    /**
     * To change the starting mintTokenId, please override this function.
     */
    function _startMintTokenId() internal view virtual returns (uint256) {
        return 10001;
    }

    /**
     * To change the starting claimTokenId, please override this function.
     */
    function _startClaimTokenId() internal view virtual returns (uint256) {
        return 1;
    }

    /**
     * @dev Burned tokens are calculated here, use _totalMinted() if you want to count just minted tokens.
     */
    function totalSupply() public view returns (uint256) {
        // Counter underflow is impossible as _burnCounter cannot be incremented
        // more than _currentIndex - _startMintTokenId() times
        unchecked {
            return (_currentMintIndex - _startMintTokenId())
            + _numClaimed
            - _burnCounter;
        }
    }

    /**
     * Returns the total amount of tokens minted in the contract.
     */
    function _totalMinted() public view returns (uint256) {
        unchecked {
            return _currentMintIndex - _startMintTokenId();
        }
    }

    /**
     * Returns the total amount of tokens claimed in the contract.
     */
    function totalClaimed() public view returns (uint256) {
        return _numClaimed;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return
        interfaceId == type(IERC721).interfaceId ||
        interfaceId == type(IERC721Metadata).interfaceId ||
        super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view override returns (uint256) {
        if (owner == address(0)) revert BalanceQueryForZeroAddress();
        return uint256(_addressData[owner].balance);
    }

    /**
     * Returns the number of tokens minted by `owner`.
     */
    function _numberMinted(address owner) internal view returns (uint256) {
        return uint256(_addressData[owner].numberMinted);
    }

    /**
     * Returns the number of tokens burned by or on behalf of `owner`.
     */
    function _numberBurned(address owner) internal view returns (uint256) {
        return uint256(_addressData[owner].numberBurned);
    }

    /**
     * Returns the auxillary data for `owner`. (e.g. number of whitelist mint slots used).
     */
    function _getAux(address owner) internal view returns (uint64) {
        return _addressData[owner].aux;
    }

    /**
     * Sets the auxillary data for `owner`. (e.g. number of whitelist mint slots used).
     * If there are multiple variables, please pack them into a uint64.
     */
    function _setAux(address owner, uint64 aux) internal {
        _addressData[owner].aux = aux;
    }

    /**
     * Gas spent here starts off proportional to the maximum mint batch size.
     * It gradually moves to O(1) as tokens get transferred around in the collection over time.
     */
    function _ownershipOf(uint256 tokenId) internal view returns (TokenOwnership memory, uint256 ownershipIndex) {
        uint256 curr = tokenId;

        TokenOwnership memory ownership = _ownerships[curr];
        if (!ownership.burned) {
            if (ownership.addr != address(0)) {
                return (ownership, tokenId);
            } else if (_startMintTokenId() <= curr && curr < _currentMintIndex) {
                // Invariant:
                // There will always be an ownership that has an address and is not burned
                // before an ownership that does not have an address and is not burned.
                // Hence, curr will not underflow.
                unchecked {
                    while (true) {
                        curr--;
                        ownership = _ownerships[curr];
                        if (ownership.addr != address(0)) {
                            return (ownership, curr);
                        }
                    }
                }
            } else if (_startClaimTokenId() <= curr && curr < _startMintTokenId()) {
                // Invariant:
                // These tokens are claimed in random order, but there will always be
                // an ownership that has an address and is not
                // burned within _maxBatchSize below tokenId.
                // Could underflow, so don't wrap in unchecked.
                uint256 lowestTokenToCheck = _startClaimTokenId();
                if (tokenId >= _maxBatchSize) {
                    lowestTokenToCheck = tokenId - _maxBatchSize + 1;
                }
                for (; curr >= lowestTokenToCheck && curr >= _startClaimTokenId(); curr--) {
                    ownership = _ownerships[curr];
                    if ((ownership.addr != address(0)) && ((curr + ownership.quantity - 1) >= tokenId)) {
                        return (ownership, curr);
                    }
                }
            }
        }
        revert OwnerQueryForNonexistentToken();
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view override returns (address) {
        (TokenOwnership memory ownership, ) = _ownershipOf(tokenId);
        return ownership.addr;
    }

    /**
     * @dev See {IERC721Metadata-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC721Metadata-symbol}.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        if (!_exists(tokenId)) revert URIQueryForNonexistentToken();

        string memory baseURI = _baseURI();
        return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : '';
    }

    /**
     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
     * by default, can be overriden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return '';
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public override {
        address owner = ERC721AClaimable.ownerOf(tokenId);
        if (to == owner) revert ApprovalToCurrentOwner();

        if (_msgSender() != owner && !isApprovedForAll(owner, _msgSender())) {
            revert ApprovalCallerNotOwnerNorApproved();
        }

        _approve(to, tokenId, owner);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view override returns (address) {
        if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        if (operator == _msgSender()) revert ApproveToCaller();

        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_msgSender(), operator, approved);
    }

    /**
     * @dev See {IERC721-isApprovedForAll}.
     */
    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        safeTransferFrom(from, to, tokenId, '');
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override {
        _transfer(from, to, tokenId);
        if (to.isContract() && !_checkContractOnERC721Received(from, to, tokenId, _data)) {
            revert TransferToNonERC721ReceiverImplementer();
        }
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`) or claimed (`_claim`).
     */
    function _exists(uint256 tokenId) internal view returns (bool) {
        return ((_startMintTokenId() <= tokenId && tokenId < _currentMintIndex) ||
        _isClaimed(tokenId)) &&
        !_ownerships[tokenId].burned;
    }

    /**
    * @dev Returns whether `tokenId` has been claimed.
    */
    function _isClaimed(uint256 tokenId) internal view returns (bool) {
        uint256 curr = tokenId;
        if (_startClaimTokenId() <= curr && curr < _startMintTokenId()) {
            // Invariant:
            // These tokens are minted in random order, but if the token exists,
            // there will always be an ownership that has an address and is not
            // burned within _maxBatchSize below tokenId.
            uint256 lowestTokenToCheck = _startClaimTokenId();
            if (tokenId >= _maxBatchSize) {
                lowestTokenToCheck = tokenId - _maxBatchSize + 1;
            }
            for (; curr >= lowestTokenToCheck && curr >= _startClaimTokenId(); curr--) {
                TokenOwnership memory ownership = _ownerships[curr];
                if (ownership.addr != address(0)) {
                    return (curr + ownership.quantity - 1) >= tokenId;
                }
            }
        }
        return false;
    }

    /**
     * @dev Equivalent to `_safeMint(to, quantity, '')`.
     */
    function _safeMint(address to, uint256 quantity) internal {
        _safeMint(to, quantity, '');
    }

    /**
     * @dev Safely mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - If `to` refers to a smart contract, it must implement
     *   {IERC721Receiver-onERC721Received}, which is called for each safe transfer.
     * - `quantity` must be greater than 0.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(
        address to,
        uint256 quantity,
        bytes memory _data
    ) internal {
        uint256 startTokenId = _currentMintIndex;
        if (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();

        _beforeTokenTransfers(address(0), to, startTokenId, quantity);

        // Overflows are incredibly unrealistic.
        // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
        // updatedIndex overflows if _currentMintIndex + quantity > 1.2e77 (2**256) - 1
        unchecked {
            _addressData[to].balance += uint64(quantity);
            _addressData[to].numberMinted += uint64(quantity);

            _ownerships[startTokenId].addr = to;
            _ownerships[startTokenId].startTimestamp = uint64(block.timestamp);

            uint256 updatedIndex = startTokenId;
            uint256 end = updatedIndex + quantity;

            if (to.isContract()) {
                do {
                    emit Transfer(address(0), to, updatedIndex);
                    if (!_checkContractOnERC721Received(address(0), to, updatedIndex++, _data)) {
                        revert TransferToNonERC721ReceiverImplementer();
                    }
                } while (updatedIndex != end);
                // Reentrancy protection
                if (_currentMintIndex != startTokenId) revert();
            } else {
                do {
                    emit Transfer(address(0), to, updatedIndex++);
                } while (updatedIndex != end);
            }
            _currentMintIndex = updatedIndex;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @dev Mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `quantity` must be greater than 0.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 quantity) internal {
        uint256 startTokenId = _currentMintIndex;
        if (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();

        _beforeTokenTransfers(address(0), to, startTokenId, quantity);

        // Overflows are incredibly unrealistic.
        // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
        // updatedIndex overflows if _currentMintIndex + quantity > 1.2e77 (2**256) - 1
        unchecked {
            _addressData[to].balance += uint64(quantity);
            _addressData[to].numberMinted += uint64(quantity);

            _ownerships[startTokenId].addr = to;
            _ownerships[startTokenId].startTimestamp = uint64(block.timestamp);

            uint256 updatedIndex = startTokenId;
            uint256 end = updatedIndex + quantity;

            do {
                emit Transfer(address(0), to, updatedIndex++);
            } while (updatedIndex != end);

            _currentMintIndex = updatedIndex;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
 * @dev Mints `quantity` tokens and transfers them to `to`.
     *
     * IMPORTANT NOTE: This operation is unsafe, since there is no check to ensure a taken has not been claimed.
     * Callers should check that a token hasn't been claimed before calling.
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `quantity` must be greater than 0.
     *
     * Emits a {Transfer} event.
     */
    function _claim(address to, uint256 startTokenId, uint256 quantity) internal {
        if (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();

        _beforeTokenTransfers(address(0), to, startTokenId, quantity);

        // Overflows are incredibly unrealistic.
        // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
        // updatedIndex overflows if _currentAirdropIndex + quantity > 1.2e77 (2**256) - 1
        unchecked {
            _addressData[to].balance += uint64(quantity);
            _addressData[to].numberMinted += uint64(quantity);

            _ownerships[startTokenId].addr = to;
            _ownerships[startTokenId].startTimestamp = uint64(block.timestamp);
            _ownerships[startTokenId].quantity = quantity;

            uint256 updatedIndex = startTokenId;
            uint256 end = updatedIndex + quantity;

            do {
                emit Transfer(address(0), to, updatedIndex++);
            } while (updatedIndex != end);

            _numClaimed += quantity;

            _afterTokenTransfers(address(0), to, startTokenId, quantity);
        }
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) private {
        (TokenOwnership memory prevOwnership, uint256 prevOwnershipIndex) = _ownershipOf(tokenId);

        if (prevOwnership.addr != from) revert TransferFromIncorrectOwner();

        bool isApprovedOrOwner = (_msgSender() == from ||
        isApprovedForAll(from, _msgSender()) ||
        getApproved(tokenId) == _msgSender());

        if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        if (to == address(0)) revert TransferToZeroAddress();

        _beforeTokenTransfers(from, to, tokenId, 1);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId, from);

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as tokenId would have to be 2**256.
        TokenOwnership storage currSlot = _ownerships[tokenId];
        unchecked {
            _addressData[from].balance -= 1;
            _addressData[to].balance += 1;

            currSlot.addr = to;
            currSlot.startTimestamp = uint64(block.timestamp);
        }

        // Consider removing this.  It's not likely needed, as
        // - ownership checks for currSlot now have an ownership record and will immediately return
        // - now that currSlot is set, we will only hit the _ownerships[prevOwnershipIndex] ownership record
        // for ownership checks between _ownerships[prevOwnershipIndex] and currSlot.  Any checks above currSlot will
        // be covered by nextSlot, which is set below.
        uint256 prevOwnershipQuantity = prevOwnership.quantity;
        if (_startClaimTokenId() <= tokenId && tokenId < _startMintTokenId()) {
            currSlot.quantity = 1;
            _ownerships[prevOwnershipIndex].quantity = tokenId - prevOwnershipIndex + 1;
        }

        // If the ownership slot of tokenId+1 is not explicitly set, that means the transfer initiator owns it.
        // Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls.
        uint256 nextTokenId = tokenId + 1;
        TokenOwnership storage nextSlot = _ownerships[nextTokenId];
        if (nextSlot.addr == address(0)) {
            // This will suffice for checking _exists(nextTokenId) on minted tokens,
            // as a burned slot cannot contain the zero address.
            if ((_startMintTokenId() <= tokenId && tokenId < _currentMintIndex)) {
                nextSlot.addr = from;
                nextSlot.startTimestamp = prevOwnership.startTimestamp;
            } else if ((prevOwnershipIndex + prevOwnershipQuantity - 1) > tokenId) {
                nextSlot.addr = from;
                nextSlot.startTimestamp = prevOwnership.startTimestamp;
                nextSlot.quantity = prevOwnershipIndex + prevOwnershipQuantity - 1 - tokenId;
            }
        }

        emit Transfer(from, to, tokenId);
        _afterTokenTransfers(from, to, tokenId, 1);
    }

    /**
     * @dev Equivalent to `_burn(tokenId, false)`.
     */
    function _burn(uint256 tokenId) internal virtual {
        _burn(tokenId, false);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId, bool approvalCheck) internal virtual {
        (TokenOwnership memory prevOwnership, uint256 prevOwnershipIndex) = _ownershipOf(tokenId);

        address from = prevOwnership.addr;

        if (approvalCheck) {
            bool isApprovedOrOwner = (_msgSender() == from ||
            isApprovedForAll(from, _msgSender()) ||
            getApproved(tokenId) == _msgSender());

            if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        }

        _beforeTokenTransfers(from, address(0), tokenId, 1);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId, from);

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as tokenId would have to be 2**256.
        TokenOwnership storage currSlot = _ownerships[tokenId];
        unchecked {
            AddressData storage addressData = _addressData[from];
            addressData.balance -= 1;
            addressData.numberBurned += 1;

            // Keep track of who burned the token, and the timestamp of burning.
            currSlot.addr = from;
            currSlot.startTimestamp = uint64(block.timestamp);
            currSlot.burned = true;
        }

        // Consider removing this.  It's not likely needed, as
        // - ownership checks for currSlot now have an ownership record and will immediately return
        // - now that currSlot is set, we will only hit the _ownerships[prevOwnershipIndex] ownership record
        // for ownership checks between _ownerships[prevOwnershipIndex] and currSlot.  Any checks above currSlot will
        // be covered by nextSlot, which is set below.
        uint256 prevOwnershipQuantity = prevOwnership.quantity;
        if (_startClaimTokenId() <= tokenId && tokenId < _startMintTokenId()) {
            currSlot.quantity = 1;
            _ownerships[prevOwnershipIndex].quantity = tokenId - prevOwnershipIndex + 1;
        }

        // If the ownership slot of tokenId+1 is not explicitly set, that means the burn initiator owns it.
        // Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls.
        uint256 nextTokenId = tokenId + 1;
        TokenOwnership storage nextSlot = _ownerships[nextTokenId];
        if (nextSlot.addr == address(0)) {
            // This will suffice for checking _exists(nextTokenId),
            // as a burned slot cannot contain the zero address.
            if ((_startMintTokenId() <= tokenId && tokenId < _currentMintIndex)) {
                nextSlot.addr = from;
                nextSlot.startTimestamp = prevOwnership.startTimestamp;
            } else if ((prevOwnershipIndex + prevOwnershipQuantity - 1) > tokenId) {
                nextSlot.addr = from;
                nextSlot.startTimestamp = prevOwnership.startTimestamp;
                nextSlot.quantity = prevOwnershipIndex + prevOwnershipQuantity - 1 - tokenId;
            }
        }

        emit Transfer(from, address(0), tokenId);
        _afterTokenTransfers(from, address(0), tokenId, 1);

        // Overflow not possible, as _burnCounter cannot exceed _currentMintIndex+_currentAirdropIndex times.
        unchecked {
            _burnCounter++;
        }
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits a {Approval} event.
     */
    function _approve(
        address to,
        uint256 tokenId,
        address owner
    ) private {
        _tokenApprovals[tokenId] = to;
        emit Approval(owner, to, tokenId);
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkContractOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
            return retval == IERC721Receiver(to).onERC721Received.selector;
        } catch (bytes memory reason) {
            if (reason.length == 0) {
                revert TransferToNonERC721ReceiverImplementer();
            } else {
                assembly {
                    revert(add(32, reason), mload(reason))
                }
            }
        }
    }

    /**
     * @dev Hook that is called before a set of serially-ordered token ids are about to be transferred. This includes minting.
     * And also called before burning one token.
     *
     * startTokenId - the first token id to be transferred
     * quantity - the amount to be transferred
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, `tokenId` will be burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _beforeTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}

    /**
     * @dev Hook that is called after a set of serially-ordered token ids have been transferred. This includes
     * minting.
     * And also called after one token has been burned.
     *
     * startTokenId - the first token id to be transferred
     * quantity - the amount to be transferred
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been
     * transferred to `to`.
     * - When `from` is zero, `tokenId` has been minted for `to`.
     * - When `to` is zero, `tokenId` has been burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _afterTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}
}

File 6 of 17 : IChainRunnersRenderer.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.4;

import "../core/ChainRunnersTypes.sol";

interface IChainRunnersRenderer {
    function tokenURI(uint256 tokenId, ChainRunnersTypes.ChainRunner memory runnerData) external view returns (string memory);
}

File 7 of 17 : IChainRunners.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.4;

import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol";
import "../core/ChainRunnersTypes.sol";

interface IChainRunners is IERC721Enumerable {
    function getDna(uint256 _tokenId) external view returns (uint256);
}

File 8 of 17 : Context.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

File 9 of 17 : IERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;
}

File 10 of 17 : IERC721Receiver.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

File 11 of 17 : IERC721Metadata.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../IERC721.sol";

/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {
    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the token collection symbol.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) external view returns (string memory);
}

File 12 of 17 : Address.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

File 13 of 17 : Strings.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

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

File 14 of 17 : ERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC165.sol";

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

File 15 of 17 : IERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

File 16 of 17 : ChainRunnersTypes.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.4;

interface ChainRunnersTypes {
    struct ChainRunner {
        uint256 dna;
    }
}

File 17 of 17 : IERC721Enumerable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../IERC721.sol";

/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {
    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);

    /**
     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
     * Use along with {totalSupply} to enumerate all tokens.
     */
    function tokenByIndex(uint256 index) external view returns (uint256);
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 2000,
    "details": {
      "yul": true,
      "yulDetails": {
        "stackAllocation": true,
        "optimizerSteps": "dhfoDgvulfnTUtnIf"
      }
    }
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"uint256","name":"mintCollectionSize_","type":"uint256"},{"internalType":"uint256","name":"amountForDevs_","type":"uint256"},{"internalType":"address","name":"genesisContractAddress_","type":"address"},{"internalType":"address","name":"xrRendererContractAddress_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApprovalToCurrentOwner","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","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":[],"name":"MAX_BATCH_SIZE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_PER_ADDRESS_DURING_ALLOWLIST_MINT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_PER_TRANSACTION_DURING_PUBLIC","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRICE_PER_TOKEN","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_totalMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"allowlist","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allowlistStartTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"amountForDevs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"burningStartTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimStartTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"claimsRemaining","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"genesisContractAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getDna","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isAllowlistSaleActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isBurningActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isClaimActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"isClaimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPublicSaleActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_quantity","type":"uint256"},{"internalType":"bytes32[]","name":"_merkleProof","type":"bytes32[]"}],"name":"mintAllowlist","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintCollectionSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_quantity","type":"uint256"}],"name":"mintDev","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_quantity","type":"uint256"}],"name":"mintPublic","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numAvailableTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"ownershipStartTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicSaleStartTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_revealSeed","type":"uint256"}],"name":"reveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_root","type":"bytes32"}],"name":"setAllowlistMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_allowlistStartTimestamp","type":"uint256"}],"name":"setAllowlistSaleStartTimestamp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"setBurningStartTimestamp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_claimStartTimestamp","type":"uint256"}],"name":"setClaimStartTimestamp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_publicSaleStartTimestamp","type":"uint256"}],"name":"setPublicSaleStartTimestamp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_xrRenderingContractAddress","type":"address"}],"name":"setXRRenderingContractAddress","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":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalClaimed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"xrRendererContractAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

60c0604052612710600e553480156200001757600080fd5b5060405162003eca38038062003eca8339810160408190526200003a916200022e565b6040518060400160405280601081526020016f21b430b4b710293ab73732b939902c2960811b815250604051806040016040528060028152602001612c2960f11b81525062000098620000926200011460201b60201c565b62000118565b8151620000ad90600590602085019062000168565b508051620000c390600690602084019062000168565b5061271160019081556005600355600b55505060a093909352608091909152600c80546001600160a01b039283166001600160a01b031991821617909155600d805492909316911617905562000310565b3390565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b8280546200017690620002a8565b90600052602060002090601f0160209004810192826200019a5760008555620001e5565b82601f10620001b557805160ff1916838001178555620001e5565b82800160010185558215620001e5579182015b82811115620001e5578251825591602001919060010190620001c8565b50620001f3929150620001f7565b5090565b5b80821115620001f35760008155600101620001f8565b80516200021b81620002ef565b92915050565b80516200021b8162000309565b6000806000806080858703121562000244578384fd5b620002528685870162000221565b93506020620002648782880162000221565b935050604062000277878288016200020e565b92505060606200028a878288016200020e565b91505092959194509250565b60006001600160a01b0382166200021b565b600281046001821680620002bd57607f821691505b60208210811415620002d357620002d3620002d9565b50919050565b634e487b7160e01b600052602260045260246000fd5b620002fa8162000296565b81146200030657600080fd5b50565b80620002fa565b60805160a051613b5c6200036e6000396000818161049e01528181610f160152818161109f01528181611174015281816119880152611aef01526000818161098d01528181610ef5015281816119670152611b6f0152613b5c6000f3fe6080604052600436106103545760003560e01c8063833b9499116101bb578063cfdbf254116100f7578063e985e9c511610095578063f6d853cf1161006f578063f6d853cf1461091b578063f95df4141461093b578063fba7d7cb1461095b578063fbe1aa511461097b57600080fd5b8063e985e9c51461089f578063efd0cbf9146108e8578063f2fde38b146108fb57600080fd5b8063d7822c99116100d1578063d7822c9914610853578063dcb32d2014610814578063dfc5d02f14610869578063e8fee1051461087f57600080fd5b8063cfdbf25414610814578063d1058e5914610829578063d54ad2a11461083e57600080fd5b8063ab5f254c11610164578063c2ca0ac51161013e578063c2ca0ac51461079e578063c87b56dd146107be578063cc55a9e5146107de578063cefa7b6d146107f457600080fd5b8063ab5f254c14610749578063b88d4fde1461075e578063c0278d711461077e57600080fd5b80639e34070f116101955780639e34070f146106dc578063a22cb465146106fc578063a7cd52cb1461071c57600080fd5b8063833b94991461068d5780638da5cb5b146106a957806395d89b41146106c757600080fd5b8063413ac78d1161029557806370a0823111610233578063765947191161020d5780637659471914610622578063775fe52f146106425780637ec0a3a4146106585780637fc278031461067857600080fd5b806370a08231146105d3578063715018a6146105f3578063736bf5911461060857600080fd5b806342966c681161026f57806342966c681461055e578063454814401461057e578063571272471461059e5780636352211e146105b357600080fd5b8063413ac78d14610508578063422627c31461051e57806342842e0e1461053e57600080fd5b806318160ddd116103025780632466b74a116102dc5780632466b74a1461048c5780633671f8cf146104c057806337c7d97c146104d35780633ccfd60b146104f357600080fd5b806318160ddd146104425780631e84c4131461045757806323b872dd1461046c57600080fd5b8063081812fc11610333578063081812fc146103c6578063095ea7b3146103f357806309ad63fd1461041557600080fd5b806210f81e1461035957806301ffc9a71461038457806306fdde03146103a4575b600080fd5b34801561036557600080fd5b5061036e6109af565b60405161037b91906137a9565b60405180910390f35b34801561039057600080fd5b5061036e61039f36600461314c565b6109cb565b3480156103b057600080fd5b506103b9610a68565b60405161037b91906137b7565b3480156103d257600080fd5b506103e66103e136600461312f565b610afa565b60405161037b91906136c5565b3480156103ff57600080fd5b5061041361040e366004613101565b610b57565b005b34801561042157600080fd5b50610435610430366004612fbd565b610c34565b60405161037b91906138d8565b34801561044e57600080fd5b50610435610da2565b34801561046357600080fd5b5061036e610dbe565b34801561047857600080fd5b50610413610487366004613012565b610dd8565b34801561049857600080fd5b506104357f000000000000000000000000000000000000000000000000000000000000000081565b6104356104ce3660046131d8565b610de3565b3480156104df57600080fd5b506104136104ee36600461312f565b610fc9565b3480156104ff57600080fd5b50610413610ff8565b34801561051457600080fd5b50610435600e5481565b34801561052a57600080fd5b5061043561053936600461312f565b61108d565b34801561054a57600080fd5b50610413610559366004613012565b6111d7565b34801561056a57600080fd5b5061041361057936600461312f565b6111f2565b34801561058a57600080fd5b50610413610599366004612fbd565b611221565b3480156105aa57600080fd5b5061036e61127a565b3480156105bf57600080fd5b506103e66105ce36600461312f565b611294565b3480156105df57600080fd5b506104356105ee366004612fbd565b6112a9565b3480156105ff57600080fd5b50610413611311565b34801561061457600080fd5b506001546127101901610435565b34801561062e57600080fd5b50600d546103e6906001600160a01b031681565b34801561064e57600080fd5b5061043560125481565b34801561066457600080fd5b5061043561067336600461312f565b611347565b34801561068457600080fd5b5061036e611369565b34801561069957600080fd5b5061043567016345785d8a000081565b3480156106b557600080fd5b506000546001600160a01b03166103e6565b3480156106d357600080fd5b506103b9611383565b3480156106e857600080fd5b5061036e6106f736600461312f565b611392565b34801561070857600080fd5b506104136107173660046130d3565b6113eb565b34801561072857600080fd5b50610435610737366004612fbd565b60146020526000908152604090205481565b34801561075557600080fd5b50610435600181565b34801561076a57600080fd5b5061041361077936600461305d565b6114bb565b34801561078a57600080fd5b5061041361079936600461312f565b61150c565b3480156107aa57600080fd5b506104136107b936600461312f565b61153b565b3480156107ca57600080fd5b506103b96107d936600461312f565b61156a565b3480156107ea57600080fd5b50610435603f5481565b34801561080057600080fd5b50600c546103e6906001600160a01b031681565b34801561082057600080fd5b50610435600581565b34801561083557600080fd5b5061041361168e565b34801561084a57600080fd5b50600254610435565b34801561085f57600080fd5b5061043560115481565b34801561087557600080fd5b5061043560135481565b34801561088b57600080fd5b5061041361089a36600461312f565b6118ee565b3480156108ab57600080fd5b5061036e6108ba366004612fda565b6001600160a01b039182166000908152600a6020908152604080832093909416825291909152205460ff1690565b6104356108f636600461312f565b61191d565b34801561090757600080fd5b50610413610916366004612fbd565b611a3b565b34801561092757600080fd5b5061041361093636600461312f565b603f55565b34801561094757600080fd5b5061041361095636600461312f565b611a94565b34801561096757600080fd5b5061041361097636600461312f565b611ac3565b34801561098757600080fd5b506104357f000000000000000000000000000000000000000000000000000000000000000081565b60006012546000141580156109c657506012544210155b905090565b60006001600160e01b031982167f80ac58cd000000000000000000000000000000000000000000000000000000001480610a2e57506001600160e01b031982167f5b5e139f00000000000000000000000000000000000000000000000000000000145b80610a6257507f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b03198316145b92915050565b606060058054610a7790613a01565b80601f0160208091040260200160405190810160405280929190818152602001828054610aa390613a01565b8015610af05780601f10610ac557610100808354040283529160200191610af0565b820191906000526020600020905b815481529060010190602001808311610ad357829003601f168201915b5050505050905090565b6000610b0582611be4565b610b3b576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506000908152600960205260409020546001600160a01b031690565b6000610b6282611294565b9050806001600160a01b0316836001600160a01b03161415610bb0576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336001600160a01b03821614801590610bed57506001600160a01b0381166000908152600a6020908152604080832033845290915290205460ff16155b15610c24576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c2f838383611c2d565b505050565b600c546040517f70a082310000000000000000000000000000000000000000000000000000000081526000916001600160a01b031690829082906370a0823190610c829087906004016136c5565b60206040518083038186803b158015610c9a57600080fd5b505afa158015610cae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cd291906131bb565b90506000805b82811015610d99576040517f2f745c590000000000000000000000000000000000000000000000000000000081526000906001600160a01b03861690632f745c5990610d2a908a908690600401613717565b60206040518083038186803b158015610d4257600080fd5b505afa158015610d56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d7a91906131bb565b9050610d8581611392565b610d90576001909201915b50600101610cd8565b50949350505050565b6000600454600254610db361271190565b600154030103905090565b60006011546000141580156109c657505060115442101590565b610c2f838383611c96565b6000323314610e0d5760405162461bcd60e51b8152600401610e04906138a8565b60405180910390fd5b610e156109af565b610e315760405162461bcd60e51b8152600401610e0490613858565b610e9883838080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050601554604051909250610e7d91503390602001613681565b60405160208183030381529060405280519060200120611fe9565b610eb45760405162461bcd60e51b8152600401610e0490613808565b33600090815260146020526040902054600190610ed290869061393f565b1115610ef05760405162461bcd60e51b8152600401610e0490613828565b610f3a7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000061398a565b84610f49600154612710190190565b610f53919061393f565b1115610f715760405162461bcd60e51b8152600401610e0490613818565b6000610f858567016345785d8a000061396b565b336000818152601460205260409020805488019055909150610fa790866120a4565b610fb081612114565b84600154610fbe919061398a565b9150505b9392505050565b6000546001600160a01b03163314610ff35760405162461bcd60e51b8152600401610e0490613838565b601355565b6000546001600160a01b031633146110225760405162461bcd60e51b8152600401610e0490613838565b604051600090339047908381818185875af1925050503d8060008114611064576040519150601f19603f3d011682016040523d82523d6000602084013e611069565b606091505b505090508061108a5760405162461bcd60e51b8152600401610e04906138c8565b50565b600c546000906001600160a01b0316817f00000000000000000000000000000000000000000000000000000000000000008411611160576040517f422627c30000000000000000000000000000000000000000000000000000000081526001600160a01b0383169063422627c3906111099087906004016138d8565b60206040518083038186803b15801561112157600080fd5b505afa158015611135573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061115991906131bb565b9050610fc2565b6000848152601060205260409020546111997f000000000000000000000000000000000000000000000000000000000000000082613a88565b603e546111a6919061393f565b6040516020016111b691906136b3565b60408051601f19818403018152919052805160209091012095945050505050565b610c2f838383604051806020016040528060008152506114bb565b6111fa61127a565b6112165760405162461bcd60e51b8152600401610e04906137e8565b61108a816001612176565b6000546001600160a01b0316331461124b5760405162461bcd60e51b8152600401610e0490613838565b600d805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6000603f546000141580156109c6575050603f5442101590565b6000806112a08361249a565b50519392505050565b60006001600160a01b0382166112eb576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001600160a01b031660009081526008602052604090205467ffffffffffffffff1690565b6000546001600160a01b0316331461133b5760405162461bcd60e51b8152600401610e0490613838565b61134560006126f7565b565b6000806113538361249a565b506020015167ffffffffffffffff169392505050565b60006013546000141580156109c657505060135442101590565b606060068054610a7790613a01565b6000806113a161010084613957565b905060006113b161010085613a88565b90506000601683602881106113d657634e487b7160e01b600052603260045260246000fd5b0154600190921b918216909114949350505050565b6001600160a01b03821633141561142e576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000818152600a602090815260408083206001600160a01b03871680855292529182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151517905590519091907f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31906114af9085906137a9565b60405180910390a35050565b6114c6848484611c96565b6001600160a01b0383163b151580156114e857506114e684848484612754565b155b15611506576040516368d2bf6b60e11b815260040160405180910390fd5b50505050565b6000546001600160a01b031633146115365760405162461bcd60e51b8152600401610e0490613838565b601255565b6000546001600160a01b031633146115655760405162461bcd60e51b8152600401610e0490613838565b603e55565b606061157582611be4565b6115915760405162461bcd60e51b8152600401610e0490613848565b600d546001600160a01b031615806115a95750603e54155b156115c257505060408051602081019091526000815290565b600d546040805160208101909152600081526001600160a01b03909116906115e98461108d565b81526040517fa62f8deb0000000000000000000000000000000000000000000000000000000081526001600160a01b0383169063a62f8deb9061163290879085906004016138e6565b60006040518083038186803b15801561164a57600080fd5b505afa15801561165e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526116869190810190613186565b949350505050565b611696611369565b6116b25760405162461bcd60e51b8152600401610e04906137f8565b600c546040517f70a0823100000000000000000000000000000000000000000000000000000000815233916001600160a01b03169060009082906370a08231906117009086906004016136c5565b60206040518083038186803b15801561171857600080fd5b505afa15801561172c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061175091906131bb565b905061177f604051806060016040528060006001600160a01b0316815260200160008152602001600081525090565b60005b828110156118e7576040517f2f745c590000000000000000000000000000000000000000000000000000000081526000906001600160a01b03861690632f745c59906117d49089908690600401613717565b60206040518083038186803b1580156117ec57600080fd5b505afa158015611800573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061182491906131bb565b905061182f81611392565b6118de57602083015161185b576001600160a01b038616835260208301819052600160408401526118b3565b808360400151846020015101141580611878575060058360400151145b156118a75761189483600001518460200151856040015161287d565b60208301819052600160408401526118b3565b60408301805160010190525b600184038214156118d5576118d583600001518460200151856040015161287d565b6118de816129f7565b50600101611782565b5050505050565b6000546001600160a01b031633146119185760405162461bcd60e51b8152600401610e0490613838565b601155565b600032331461193e5760405162461bcd60e51b8152600401610e04906138a8565b611946610dbe565b6119625760405162461bcd60e51b8152600401610e0490613868565b6119ac7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000061398a565b826119bb600154612710190190565b6119c5919061393f565b11156119e35760405162461bcd60e51b8152600401610e0490613818565b6005821115611a045760405162461bcd60e51b8152600401610e0490613898565b611a0e33836120a4565b611a28611a238367016345785d8a000061396b565b612114565b81600154610a62919061398a565b919050565b6000546001600160a01b03163314611a655760405162461bcd60e51b8152600401610e0490613838565b6001600160a01b038116611a8b5760405162461bcd60e51b8152600401610e04906137c8565b61108a816126f7565b6000546001600160a01b03163314611abe5760405162461bcd60e51b8152600401610e0490613838565b601555565b6000546001600160a01b03163314611aed5760405162461bcd60e51b8152600401610e0490613838565b7f000000000000000000000000000000000000000000000000000000000000000081611b1d600154612710190190565b611b27919061393f565b1115611b455760405162461bcd60e51b8152600401610e04906138b8565b611b50600582613a88565b15611b6d5760405162461bcd60e51b8152600401610e04906137d8565b7f0000000000000000000000000000000000000000000000000000000000000000811115611bad5760405162461bcd60e51b8152600401610e0490613878565b6000611bba600583613957565b905060005b81811015610c2f57611bd23360056120a4565b80611bdc81613a5b565b915050611bbf565b60008161271111158015611bf9575060015482105b80611c085750611c0882612a67565b8015610a62575050600090815260076020526040902054600160e01b900460ff161590565b600082815260096020526040808220805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b600080611ca28361249a565b91509150846001600160a01b031682600001516001600160a01b031614611cf5576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000336001600160a01b0387161480611d3157506001600160a01b0386166000908152600a6020908152604080832033845290915290205460ff165b80611d4c575033611d4185610afa565b6001600160a01b0316145b905080611d85576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038516611dc5576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611dd160008588611c2d565b60008481526007602090815260408083206001600160a01b03808b1685526008909352818420805460001967ffffffffffffffff80831691909101811667ffffffffffffffff1992831617909255938a168086529290942080548086166001018616941693909317909255815442909316600160a01b026001600160e01b031990931617919091178155606084015185611e69600190565b11158015611e78575061271186105b15611eab57600182810155611e8d848761398a565b611e9890600161393f565b6000858152600760205260409020600101555b6000611eb887600161393f565b60008181526007602052604090208054919250906001600160a01b0316611f9c578761271111158015611eec575060015488105b15611f27578054602088015167ffffffffffffffff16600160a01b026001600160e01b03199091166001600160a01b038c1617178155611f9c565b876001611f34858961393f565b611f3e919061398a565b1115611f9c578054602088015167ffffffffffffffff16600160a01b026001600160e01b03199091166001600160a01b038c1617178155876001611f82858961393f565b611f8c919061398a565b611f96919061398a565b60018201555b87896001600160a01b03168b6001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a450505050505050505050565b600081815b855181101561209957600086828151811061201957634e487b7160e01b600052603260045260246000fd5b6020026020010151905080831161205a57828160405160200161203d929190613693565b604051602081830303815290604052805190602001209250612086565b808360405160200161206d929190613693565b6040516020818303038152906040528051906020012092505b508061209181613a5b565b915050611fee565b509092149392505050565b600e5460005b828110156121025760006120c985846120c2816139ea565b9550612b66565b90508060106000846001546120de919061393f565b815260208101919091526040016000205550806120fa81613a5b565b9150506120aa565b5061210d8383612b96565b600e555050565b803410156121345760405162461bcd60e51b8152600401610e0490613888565b8034111561108a57336108fc61214a833461398a565b6040518115909202916000818181858888f19350505050158015612172573d6000803e3d6000fd5b5050565b6000806121828461249a565b815191935091508315612221576000336001600160a01b03831614806121cb57506001600160a01b0382166000908152600a6020908152604080832033845290915290205460ff165b806121e65750336121db87610afa565b6001600160a01b0316145b90508061221f576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b61222d60008683611c2d565b60008581526007602090815260408083206001600160a01b03851680855260089093529220805470010000000000000000000000000000000060001967ffffffffffffffff80841691909101811667ffffffffffffffff1984168117839004821660010182169092027fffffffffffffffff0000000000000000ffffffffffffffff00000000000000009093169091179190911790915582547fffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff42909216600160a01b026001600160e01b03199091169092179190911716600160e01b17815560608401518661231b600190565b1115801561232a575061271187105b1561235d5760018281015561233f848861398a565b61234a90600161393f565b6000858152600760205260409020600101555b600061236a88600161393f565b60008181526007602052604090208054919250906001600160a01b031661244e57886127111115801561239e575060015489105b156123d9578054602088015167ffffffffffffffff16600160a01b026001600160e01b03199091166001600160a01b0387161717815561244e565b8860016123e6858961393f565b6123f0919061398a565b111561244e578054602088015167ffffffffffffffff16600160a01b026001600160e01b03199091166001600160a01b03871617178155886001612434858961393f565b61243e919061398a565b612448919061398a565b60018201555b60405189906000906001600160a01b038816907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a4505060048054600101905550505050505050565b6040805160808101825260008082526020820181905291810182905260608101919091526000828152600760209081526040808320815160808101835281546001600160a01b0381168252600160a01b810467ffffffffffffffff1694820194909452600160e01b90930460ff1615159183018290526001015460608301528491906126c55780516001600160a01b031615612537579492505050565b816127111115801561254a575060015482105b156125c5575b5060001901600081815260076020908152604091829020825160808101845281546001600160a01b038116808352600160a01b820467ffffffffffffffff1694830194909452600160e01b900460ff16151593810193909352600101546060830152156125c05794909350915050565b612550565b816001111580156125d7575061271182105b156126c5576003546001908610612603576003546125f5908761398a565b61260090600161393f565b90505b808310158015612614575060018310155b156126c357600083815260076020908152604091829020825160808101845281546001600160a01b038116808352600160a01b820467ffffffffffffffff1694830194909452600160e01b900460ff16151593810193909352600101546060830152909250158015906126a25750856001836060015185612695919061393f565b61269f919061398a565b10155b156126b1575094909350915050565b826126bb816139ea565b935050612603565b505b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6040517f150b7a020000000000000000000000000000000000000000000000000000000081526000906001600160a01b0385169063150b7a02906127a29033908990889088906004016136d3565b602060405180830381600087803b1580156127bc57600080fd5b505af19250505080156127ec575060408051601f3d908101601f191682019092526127e991810190613169565b60015b612847573d80801561281a576040519150601f19603f3d011682016040523d82523d6000602084013e61281f565b606091505b50805161283f576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b0319167f150b7a0200000000000000000000000000000000000000000000000000000000149050949350505050565b6001600160a01b0383166128bd576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806128f4576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038316600081815260086020908152604080832080547fffffffffffffffffffffffffffffffff00000000000000000000000000000000811667ffffffffffffffff808316890181169182176801000000000000000067ffffffffffffffff1990941690921783900481168901811690920217909155868452600790925290912080546001600160e01b031916909217600160a01b4290921691909102178155600101819055818082015b6040516001830192906001600160a01b038716906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4808214156129a65760028054840190556118e7565b6000612a0561010083613957565b90506000612a1561010084613a88565b90506001811b60168360288110612a3c57634e487b7160e01b600052603260045260246000fd5b01541760168360288110612a6057634e487b7160e01b600052603260045260246000fd5b0155505050565b60008180600111158015612a7c575061271181105b15612b5d576003546001908410612aa857600354612a9a908561398a565b612aa590600161393f565b90505b808210158015612ab9575060018210155b15612b5b57600082815260076020908152604091829020825160808101845281546001600160a01b038116808352600160a01b820467ffffffffffffffff1694830194909452600160e01b900460ff1615159381019390935260010154606083015215612b4857846001826060015185612b33919061393f565b612b3d919061398a565b101595945050505050565b5081612b53816139ea565b925050612aa8565b505b50600092915050565b600080612b738484612bb0565b90506000612b818483613a88565b9050612b8d8185612bfb565b95945050505050565b612172828260405180602001604052806000815250612c7d565b6000823a434244612bc260018461398a565b403088604051602001612bdc989796959493929190613732565b60408051601f1981840301815291905280516020909101209392505050565b6000828152600f60205260408120548181612c17575083612c1a565b50805b6000612c2760018661398a565b9050808614610d99576000818152600f602052604090205480612c5a576000878152600f60205260409020829055612c73565b6000878152600f60205260408082208390558382528120555b5050949350505050565b6001546001600160a01b038416612cc0576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82612cf7576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038416600081815260086020908152604080832080547fffffffffffffffffffffffffffffffff00000000000000000000000000000000811667ffffffffffffffff8083168b0181169182176801000000000000000067ffffffffffffffff1990941690921783900481168b01811690920217909155858452600790925290912080546001600160e01b0319168317600160a01b42909316929092029190911790558190818501903b15612e30575b60405182906001600160a01b038816906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4612df86000878480600101955087612754565b612e15576040516368d2bf6b60e11b815260040160405180910390fd5b80821415612dad578260015414612e2b57600080fd5b612e76565b5b6040516001830192906001600160a01b038816906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a480821415612e31575b50600155611506600085838684565b6000612e98612e9384613918565b613901565b905082815260208101848484011115612eb057600080fd5b612ebb8482856139b2565b509392505050565b6000612ed1612e9384613918565b905082815260208101848484011115612ee957600080fd5b612ebb8482856139be565b8035610a6281613af4565b60008083601f840112612f10578081fd5b50813567ffffffffffffffff811115612f27578182fd5b602083019150836020820283011115612f3f57600080fd5b9250929050565b8035610a6281613b08565b8035610a6281613b10565b8035610a6281613b16565b8051610a6281613b16565b600082601f830112612f82578081fd5b8135611686848260208601612e85565b600082601f830112612fa2578081fd5b8151611686848260208601612ec3565b8051610a6281613b10565b600060208284031215612fce578081fd5b610fc283828401612ef4565b60008060408385031215612fec578081fd5b612ff884828501612ef4565b9150602061300885828601612ef4565b9150509250929050565b600080600060608486031215613026578081fd5b61303285828601612ef4565b9250602061304286828701612ef4565b925050604061305386828701612f51565b9150509250925092565b60008060008060808587031215613072578081fd5b61307e86828701612ef4565b9350602061308e87828801612ef4565b935050604061309f87828801612f51565b925050606085013567ffffffffffffffff8111156130bb578182fd5b6130c787828801612f72565b91505092959194509250565b600080604083850312156130e5578182fd5b6130f184838501612ef4565b9150602061300885828601612f46565b60008060408385031215613113578182fd5b61311f84838501612ef4565b9150602061300885828601612f51565b600060208284031215613140578081fd5b610fc283828401612f51565b60006020828403121561315d578081fd5b610fc283828401612f5c565b60006020828403121561317a578081fd5b610fc283828401612f67565b600060208284031215613197578081fd5b8082015167ffffffffffffffff8111156131af578182fd5b61168684828501612f92565b6000602082840312156131cc578081fd5b610fc283828401612fb2565b6000806000604084860312156131ec578283fd5b6131f885848601612f51565b9250602084013567ffffffffffffffff811115613213578283fd5b61321f86828701612eff565b92509250509250925092565b613234816139a1565b82525050565b613234613246826139a1565b613a76565b801515613234565b80613234565b6000613263825190565b80845260208401935061327a8185602086016139be565b601f01601f19169290920192915050565b60268152602081017f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181527f6464726573730000000000000000000000000000000000000000000000000000602082015290505b60400190565b602c8152602081017f63616e206f6e6c79206d696e742061206d756c7469706c65206f66207468652081527f6d6178426174636853697a650000000000000000000000000000000000000000602082015290506132df565b60128152602081017f6275726e696e67206e6f74206163746976650000000000000000000000000000815290505b60200190565b60138152602081017f636c61696d206973206e6f7420616374697665000000000000000000000000008152905061336b565b60108152602081017f6e6f74206f6e20616c6c6f776c697374000000000000000000000000000000008152905061336b565b60128152602081017f72656163686564206d617820737570706c7900000000000000000000000000008152905061336b565b601f8152602081017f6e6f7420656c696769626c6520666f7220616c6c6f776c697374206d696e74008152905061336b565b60208082527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572910190815261336b565b602f8152602081017f4552433732314d657461646174613a2055524920717565727920666f72206e6f81527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015290506132df565b60208082527f616c6c6f776c6973742073616c6520686173206e6f7420626567756e20796574910190815261336b565b601d8152602081017f7075626c69632073616c6520686173206e6f7420626567756e207965740000008152905061336b565b60148152602081017f7175616e7469747920697320746f6f20686967680000000000000000000000008152905061336b565b60168152602081017f4e65656420746f2073656e64206d6f7265204554482e000000000000000000008152905061336b565b60118152602081017f7175616e7469747920746f6f20686967680000000000000000000000000000008152905061336b565b601e8152602081017f7468652063616c6c657220697320616e6f7468657220636f6e747261637400008152905061336b565b60278152602081017f746f6f206d616e7920616c7265616479206d696e746564206265666f7265206481527f6576206d696e7400000000000000000000000000000000000000000000000000602082015290506132df565b600f8152602081017f7472616e73666572206661696c656400000000000000000000000000000000008152905061336b565b8051610c2f8382613253565b61368b818361323a565b601401919050565b61369d8184613253565b6020016136aa8183613253565b60200192915050565b6136bd8183613253565b602001919050565b60208101610a62828461322b565b608081016136e1828761322b565b6136ee602083018661322b565b6136fb6040830185613253565b818103606083015261370d8184613259565b9695505050505050565b60408101613725828561322b565b610fc26020830184613253565b6101008101613741828b61322b565b61374e602083018a613253565b61375b6040830189613253565b6137686060830188613253565b6137756080830187613253565b61378260a0830186613253565b61378f60c083018561322b565b61379c60e0830184613253565b9998505050505050505050565b60208101610a62828461324b565b60208082528101610fc28184613259565b60208082528101610a628161328b565b60208082528101610a62816132e5565b60208082528101610a628161333d565b60208082528101610a6281613371565b60208082528101610a62816133a3565b60208082528101610a62816133d5565b60208082528101610a6281613407565b60208082528101610a6281613439565b60208082528101610a6281613469565b60208082528101610a62816134c1565b60208082528101610a62816134f1565b60208082528101610a6281613523565b60208082528101610a6281613555565b60208082528101610a6281613587565b60208082528101610a62816135b9565b60208082528101610a62816135eb565b60208082528101610a6281613643565b60208101610a628284613253565b604081016138f48285613253565b610fc26020830184613675565b600061390c60405190565b9050611a368282613a2e565b600067ffffffffffffffff82111561393257613932613ade565b601f19601f8301166136aa565b6000821982111561395257613952613a9c565b500190565b60008261396657613966613ab2565b500490565b600081600019048311821515161561398557613985613a9c565b500290565b60008282101561399c5761399c613a9c565b500390565b60006001600160a01b038216610a62565b82818337506000910152565b60005b838110156139d95781810151838201526020016139c1565b838111156115065750506000910152565b6000816139f9576139f9613a9c565b506000190190565b600281046001821680613a1557607f821691505b60208210811415613a2857613a28613ac8565b50919050565b601f19601f830116810181811067ffffffffffffffff82111715613a5457613a54613ade565b6040525050565b6000600019821415613a6f57613a6f613a9c565b5060010190565b6000610a62826000610a628260601b90565b600082613a9757613a97613ab2565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b613afd816139a1565b811461108a57600080fd5b801515613afd565b80613afd565b6001600160e01b03198116613afd56fea26469706673582212204cbccb7ee839f3aab1163ab8a94478f690601e2d83ff82146a71a2df2c3b5b4d64736f6c63430008040033000000000000000000000000000000000000000000000000000000000000271000000000000000000000000000000000000000000000000000000000000000c800000000000000000000000097597002980134bea46250aa0510c9b90d87a5870000000000000000000000007f1d7014dddb2bf2cc9281ca0dc9441fa9d05f7a

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

000000000000000000000000000000000000000000000000000000000000271000000000000000000000000000000000000000000000000000000000000000c800000000000000000000000097597002980134bea46250aa0510c9b90d87a5870000000000000000000000007f1d7014dddb2bf2cc9281ca0dc9441fa9d05f7a

-----Decoded View---------------
Arg [0] : mintCollectionSize_ (uint256): 10000
Arg [1] : amountForDevs_ (uint256): 200
Arg [2] : genesisContractAddress_ (address): 0x97597002980134beA46250Aa0510C9B90d87A587
Arg [3] : xrRendererContractAddress_ (address): 0x7F1D7014DdDb2bF2cc9281Ca0dc9441FA9d05F7a

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000002710
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000c8
Arg [2] : 00000000000000000000000097597002980134bea46250aa0510c9b90d87a587
Arg [3] : 0000000000000000000000007f1d7014dddb2bf2cc9281ca0dc9441fa9d05f7a


Block Transaction Difficulty Gas Used Reward
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.

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.