ETH Price: $2,636.71 (+7.92%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Declare My Love141504822022-02-06 5:11:171004 days ago1644124277IN
0x21BEf541...b589083C3
0 ETH0.0016223268.84475143
Declare My Love141460522022-02-05 12:36:231004 days ago1644064583IN
0x21BEf541...b589083C3
0 ETH0.0011243547.71299673
Declare My Love140939222022-01-28 11:42:301013 days ago1643370150IN
0x21BEf541...b589083C3
0 ETH0.0023310398.91928991
Declare My Love140564102022-01-22 16:14:061018 days ago1642868046IN
0x21BEf541...b589083C3
0 ETH0.00543633230.69521558
Declare My Love140559232022-01-22 14:22:051018 days ago1642861325IN
0x21BEf541...b589083C3
0 ETH0.0023287799.8401269
Setphase140558252022-01-22 13:59:051018 days ago1642859945IN
0x21BEf541...b589083C3
0 ETH0.00386951133.59276401
Declare My Love140548822022-01-22 10:34:161019 days ago1642847656IN
0x21BEf541...b589083C3
0 ETH0.00562987238.90813007
Declare My Love140540382022-01-22 7:18:081019 days ago1642835888IN
0x21BEf541...b589083C3
0 ETH0.00309043131.14507952
Declare My Love140531892022-01-22 4:12:271019 days ago1642824747IN
0x21BEf541...b589083C3
0 ETH0.00297349126.18259853
Declare My Love140531862022-01-22 4:11:401019 days ago1642824700IN
0x21BEf541...b589083C3
0 ETH0.00269813114.49746551
Declare My Love140531572022-01-22 4:05:321019 days ago1642824332IN
0x21BEf541...b589083C3
0 ETH0.0032107136.2488373
Declare My Love140530962022-01-22 3:52:551019 days ago1642823575IN
0x21BEf541...b589083C3
0 ETH0.00266893113.31605765
Declare My Love140512942022-01-21 21:21:371019 days ago1642800097IN
0x21BEf541...b589083C3
0 ETH0.00454336192.80158769
Declare My Love140510512022-01-21 20:24:281019 days ago1642796668IN
0x21BEf541...b589083C3
0 ETH0.0057065242.16034403
Declare My Love140489202022-01-21 12:31:331020 days ago1642768293IN
0x21BEf541...b589083C3
0 ETH0.00269279114.27096137
Declare My Love140485332022-01-21 10:59:251020 days ago1642762765IN
0x21BEf541...b589083C3
0 ETH0.0022391795.02127518
Declare My Love140485272022-01-21 10:58:021020 days ago1642762682IN
0x21BEf541...b589083C3
0 ETH0.00295731125.49613792
Declare My Love140482402022-01-21 9:49:471020 days ago1642758587IN
0x21BEf541...b589083C3
0 ETH0.00254694108.08179474
Declare My Love140481552022-01-21 9:31:091020 days ago1642757469IN
0x21BEf541...b589083C3
0 ETH0.0023528899.84659233
Declare My Love140436292022-01-20 16:51:021020 days ago1642697462IN
0x21BEf541...b589083C3
0 ETH0.00317882134.8958713
Declare My Love140434892022-01-20 16:19:341020 days ago1642695574IN
0x21BEf541...b589083C3
0 ETH0.00302726128.46433599
Declare My Love140429962022-01-20 14:35:081020 days ago1642689308IN
0x21BEf541...b589083C3
0 ETH0.001939782.31290772
Declare My Love140411022022-01-20 7:38:021021 days ago1642664282IN
0x21BEf541...b589083C3
0 ETH0.00251439106.70044653
Declare My Love140401022022-01-20 3:48:271021 days ago1642650507IN
0x21BEf541...b589083C3
0 ETH0.00284273120.63395273
Declare My Love140396632022-01-20 2:03:131021 days ago1642644193IN
0x21BEf541...b589083C3
0 ETH0.00291408123.72452654
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
LoveModule

Compiler Version
v0.8.11+commit.d7f03943

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion
File 1 of 13 : LoveModule.sol
//SPDX-License-Identifier: UNLICENSE


/*
                              
    (%#(//(#      ,%(///#%,   
  %#,,,,,,,,*## #(,,,,,,,,.#( 
 (%////////////#//////////**% 
 /%///(((((Nahiko's(((((((//# 
  %#(((((((((((((((((((((((## Ò
   #%##((((((((((((((((((##/  
     %%###((((((((((((###%    
       %%###((((((((##%%      
         %%%###((###%%        
           #%%%%%%%*          
             .%%%             
            
*/


pragma solidity ^0.8.9;

import '@openzeppelin/contracts/access/Ownable.sol';
import '@openzeppelin/contracts/utils/Strings.sol';
import '@openzeppelin/contracts/utils/cryptography/ECDSA.sol';

import './NiftyForge/INiftyForge721.sol';
import './NiftyForge/Modules/NFBaseModule.sol';
import './NiftyForge/Modules/INFModuleTokenURI.sol';
import './NiftyForge/Modules/INFModuleWithRoyalties.sol';

/// @title NahikosGameModule
/// @author Simon Fremaux (@dievardump) & Nahiko
contract LoveModule is
    Ownable,
    NFBaseModule,
    INFModuleTokenURI,
    INFModuleWithRoyalties
{
    // this is because minting is secured with a Signature
    using Strings for uint256;

    // link to the skin URI
    string public skinURI;

    // link to the bones URI
    string public bonesURI;

    // contract on which this module is made to mint
    address public nftContract;

    // init the phase associated to the different phases (Skin, Flesh, Bones, Mind)
    uint _phase;

    // variable to contain the local tokenId
    uint256 public tokenId;


    address public rendererAddress;

    /// @notice constructor
    /// @param nftContract_ contract on which we mint
    /// @param rendererAddress_ contract containing the code to render the final phase
    constructor(
        address nftContract_,
        address rendererAddress_
    ) NFBaseModule("") {
        nftContract = nftContract_;
        rendererAddress = rendererAddress_;
        _phase = 1;
    }

    function supportsInterface(bytes4 interfaceId)
        public
        view
        override
        returns (bool)
    {
        return
            interfaceId == type(INFModuleWithRoyalties).interfaceId ||
            interfaceId == type(INFModuleTokenURI).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    function tokenURI(uint256 tokenId_)
        public
        view
        override
        returns (string memory)
    {
        return tokenURI(msg.sender, tokenId_);
    }

    function tokenURI(address, uint256)
        public
        view
        override
        returns (string memory)
    {
        bytes memory uriString;

        if(_phase == 3){
            string memory rendered = ICaller(rendererAddress).render(address(this));
            uriString = abi.encodePacked("data:application/json;utf8,{\"description\":\"\xE2\x9D\xA4\xEF\xB8\x8F\",\"name\":\"Anatomy Of Love\",\"attributes\":[{\"trait_type\":\"Phase\",\"value\":\"The Mind\"}],\"image\":\"data:image/svg+xml;base64,",rendered,"\"}");
        }

        else if(_phase == 2){
            uriString = abi.encodePacked("data:application/json;utf8,{\"description\":\"\xE2\x9D\xA4\xEF\xB8\x8F\",\"name\":\"Anatomy Of Love\",\"attributes\":[{\"trait_type\":\"Phase\",\"value\":\"The Bones\"}],\"animation_url\":\"",bonesURI,"\"}");
        }
        
        else if(_phase == 1){
            uriString = abi.encodePacked("data:application/json;utf8,{\"description\":\"\xE2\x9D\xA4\xEF\xB8\x8F\",\"name\":\"Anatomy Of Love\",\"attributes\":[{\"trait_type\":\"Phase\",\"value\":\"The Skin\"}],\"image\":\"",skinURI,"\"}");
        }

        return string(uriString);
    }

    function mint() external onlyOwner {
        require(tokenId == 0, "AlreadyMinted");
        // INiftyForge721.mint(address to, string memory uri, address feeRecipient, uint256 feeAmount, address transferTo ) external returns (uint256 tokenId);
        tokenId = INiftyForge721(nftContract).mint(owner(), '',  address(0), 0, address(0));
    }

    /// @inheritdoc	INFModuleWithRoyalties
    function royaltyInfo(uint256 tokenId_)
        public
        view
        override
        returns (address, uint256)
    {
        return royaltyInfo(msg.sender, tokenId_);
    }

    /// @inheritdoc    INFModuleWithRoyalties
    function royaltyInfo(address, uint256)
        public
        view
        override
        returns (address, uint256)
    {
        return (owner(), 500);
    }



    /// @notice Setter for nfts contract
    /// @param nftContract_ the contract containing the registry
    function setNFTContract(address nftContract_) external onlyOwner {
        nftContract = nftContract_;
    }


    /// @notice Setter for the skin URI
    /// @param skinURI_ the parameter containing the link
    function setSkinURI(string memory skinURI_) external onlyOwner {
        skinURI = skinURI_;
    }

    /// @notice Setter for the skin URI
    /// @param bonesURI_ the parameter containing the link
    function setbonesURI(string memory bonesURI_) external onlyOwner {
        bonesURI = bonesURI_;
    }

    /// @notice Setter for the phase of Anatomy
    /// @param newPhase the new phase to be put on
    function setphase(uint8 newPhase) external onlyOwner{
        _phase = newPhase;
    }

    event LoveDeclared(address indexed LoveSender, address indexed LoveReceiver);

    function DeclareMyLove(address LoveReceiver) public {  
        emit LoveDeclared(msg.sender, LoveReceiver);
        //emit both the lovers's love
    }

    /// @notice The function containing the painting of a heart on the NFT. The token is the canvas.
    function heart() public {
        require(false,"nope");
        assembly{
            sstore(69, 0xa00000a00000a00000ffffffffffffffffffa00000a00000a00000)

            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffff)

            sstore(69, 0x0000ff0000ff0000ff0000a00000ffffffa00000ff0000ff0000ff0000a00000)

            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffff)

            sstore(69, 0xa00000a00000a00000ffffffffffffffffffa00000a00000a00000)

            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffff) 
            
            sstore(69, 0xa00000a00000a00000ffffffffffffffffffa00000a00000a00000)

            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffff) 
            
            sstore(69, 0xa00000a00000a00000ffffffffffffffffffa00000a00000a00000) 

            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffff000000ffffff) //first black dot of the heart black
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) 
            sstore(69, 0xffffffffffffffffffffffffffffffffffffff0000001111ff0000000fff) //second heart line black/red/black
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffff) 
            
            sstore(69, 0xa00000a00000a00000ffffffffffffffffffa00000a00000a00000)

            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0x0000001110001111ff1111ff1111ff000000000abcffffffffffdfffffff) //third heart line black/red/red/red/black
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffff) 
            sstore(69, 0xfffffff1100110000ff0000ff0000ff0000ff0000ff001100fffffffffff) //fourth heart line black/red/red/red/red/red/black
            sstore(69, 0xffffffffffffffffffffffffffffffffffffff) 
            
            sstore(69, 0xa00000a00000a00000ffffffffffffffffffa00000a00000a00000)

            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffff)
            sstore(69, 0x1aa1100001100ff1100ff1100ff1100ff1100ff1100ff1111ff111111fff) //fifth line black/red/red/red/red/red/red/red/black
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0x1aa1100001100ff1100ff1100ff1100ff1100ff1100ff1111ff111111fff) //sixth line same as fifth
            sstore(69, 0xffffffffffffffffffffffffffffffffffffff) 
            
            sstore(69, 0xa00000a00000a00000ffffffffffffffffffa00000a00000a00000)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffff)
            sstore(69, 0x1aa1100001100ff1100ff1100ff1100111100ff1100ff1111ff111111fff) //seventh line black/red/red/red/black/red/red/red/black
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xaFFFFFF110022110022110022FFFFFF110022110022111122FFFFFFfffff) //last line white/black/black/black/white/black/black/black/white
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffff) 
            
            sstore(69, 0xa00000a00000a00000ffffffffffffffffffa00000a00000a00000)

            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffff) 
            
            sstore(69, 0xa00000a00000a00000ffffffffffffffffffa00000a00000a00000)

            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffff) 
            
            sstore(69, 0xa00000a00000a00000ffffffffffffffffffa00000a00000a00000)

            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            sstore(69, 0xffffffffffffffffffffffffffffffffffffff)
            
        }
    }
    
}

interface ICaller{
    function render(address addressToRender) external view returns(string memory);
}

File 2 of 13 : INFModuleWithRoyalties.sol
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import './INFModule.sol';

interface INFModuleWithRoyalties is INFModule {
    /// @notice Return royalties (recipient, basisPoint) for tokenId
    /// @dev Contrary to EIP2981, modules are expected to return basisPoint for second parameters
    ///      This in order to allow right royalties on marketplaces not supporting 2981 (like Rarible)
    /// @param tokenId token to check
    /// @return recipient and basisPoint for this tokenId
    function royaltyInfo(uint256 tokenId)
        external
        view
        returns (address recipient, uint256 basisPoint);

    /// @notice Return royalties (recipient, basisPoint) for tokenId
    /// @dev Contrary to EIP2981, modules are expected to return basisPoint for second parameters
    ///      This in order to allow right royalties on marketplaces not supporting 2981 (like Rarible)
    /// @param registry registry to check id of
    /// @param tokenId token to check
    /// @return recipient and basisPoint for this tokenId </p>
    function royaltyInfo(address registry, uint256 tokenId)
        external
        view
        returns (address recipient, uint256 basisPoint);
}

File 3 of 13 : INFModuleTokenURI.sol
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import './INFModule.sol';

interface INFModuleTokenURI is INFModule {
    function tokenURI(uint256 tokenId) external view returns (string memory);

    function tokenURI(address registry, uint256 tokenId)
        external
        view
        returns (string memory);
}

File 4 of 13 : NFBaseModule.sol
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';
import '@openzeppelin/contracts/utils/introspection/ERC165.sol';
import './INFModule.sol';

/// @title NFBaseModule
/// @author Simon Fremaux (@dievardump)
contract NFBaseModule is INFModule, ERC165 {
    using EnumerableSet for EnumerableSet.AddressSet;

    EnumerableSet.AddressSet internal _attached;

    event NewContractURI(string contractURI);

    string private _contractURI;

    modifier onlyAttached(address registry) {
        require(_attached.contains(registry), '!NOT_ATTACHED!');
        _;
    }

    constructor(string memory contractURI_) {
        _setContractURI(contractURI_);
    }

    /// @inheritdoc	INFModule
    function contractURI() external view override returns (string memory) {
        return _contractURI;
    }

    /// @inheritdoc	INFModule
    function onAttach() external override returns (bool) {
        if (_attached.add(msg.sender)) {
            return true;
        }

        revert('!ALREADY_ATTACHED!');
    }

    /// @notice this contract doesn't really care if it's enabled or not
    ///         since trying to mint on a contract where it's not enabled will fail
    /// @inheritdoc	INFModule
    function onEnable() external pure override returns (bool) {
        return true;
    }

    /// @inheritdoc	INFModule
    function onDisable() external override {}

    function _setContractURI(string memory contractURI_) internal {
        _contractURI = contractURI_;
        emit NewContractURI(contractURI_);
    }
}

File 5 of 13 : INiftyForge721.sol
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

/// @title INiftyForge721
/// @author Simon Fremaux (@dievardump)
interface INiftyForge721 {
    struct ModuleInit {
        address module;
        bool enabled;
        bool minter;
    }

    /// @notice totalSupply access
    function totalSupply() external view returns (uint256);

    /// @notice helper to know if everyone can mint or only minters
    function isMintingOpenToAll() external view returns (bool);

    /// @notice Toggle minting open to all state
    /// @param isOpen if the new state is open or not
    function setMintingOpenToAll(bool isOpen) external;

    /// @notice Mint token to `to` with `uri`
    /// @param to address of recipient
    /// @param uri token metadata uri
    /// @param feeRecipient the recipient of royalties
    /// @param feeAmount the royalties amount. From 0 to 10000
    ///        where 10000 == 100.00%; 1000 == 10.00%; 250 == 2.50%
    /// @param transferTo the address to transfer the NFT to after mint
    ///        this is used when we want to mint the NFT to the creator address
    ///        before transferring it to a recipient
    /// @return tokenId the tokenId
    function mint(
        address to,
        string memory uri,
        address feeRecipient,
        uint256 feeAmount,
        address transferTo
    ) external returns (uint256 tokenId);

    /// @notice Mint batch tokens to `to[i]` with `uri[i]`
    /// @param to array of address of recipients
    /// @param uris array of token metadata uris
    /// @param feeRecipients the recipients of royalties for each id
    /// @param feeAmounts the royalties amounts for each id. From 0 to 10000
    ///        where 10000 == 100.00%; 1000 == 10.00%; 250 == 2.50%
    /// @return tokenIds the tokenIds
    function mintBatch(
        address[] memory to,
        string[] memory uris,
        address[] memory feeRecipients,
        uint256[] memory feeAmounts
    ) external returns (uint256[] memory tokenIds);

    /// @notice Mint `tokenId` to to` with `uri`
    ///         Because not all tokenIds have incremental ids
    ///         be careful with this function, it does not increment lastTokenId
    ///         and expects the minter to actually know what it is doing.
    ///         this also means, this function does not verify _maxTokenId
    /// @param to address of recipient
    /// @param uri token metadata uri
    /// @param tokenId token id wanted
    /// @param feeRecipient the recipient of royalties
    /// @param feeAmount the royalties amount. From 0 to 10000
    ///        where 10000 == 100.00%; 1000 == 10.00%; 250 == 2.50%
    /// @param transferTo the address to transfer the NFT to after mint
    ///        this is used when we want to mint the NFT to the creator address
    ///        before transferring it to a recipient
    /// @return tokenId the tokenId
    function mint(
        address to,
        string memory uri,
        uint256 tokenId_,
        address feeRecipient,
        uint256 feeAmount,
        address transferTo
    ) external returns (uint256 tokenId);

    /// @notice Mint batch tokens to `to[i]` with `uris[i]`
    ///         Because not all tokenIds have incremental ids
    ///         be careful with this function, it does not increment lastTokenId
    ///         and expects the minter to actually know what it's doing.
    ///         this also means, this function does not verify _maxTokenId
    /// @param to array of address of recipients
    /// @param uris array of token metadata uris
    /// @param tokenIds array of token ids wanted
    /// @param feeRecipients the recipients of royalties for each id
    /// @param feeAmounts the royalties amounts for each id. From 0 to 10000
    ///        where 10000 == 100.00%; 1000 == 10.00%; 250 == 2.50%
    /// @return tokenIds the tokenIds
    function mintBatch(
        address[] memory to,
        string[] memory uris,
        uint256[] memory tokenIds,
        address[] memory feeRecipients,
        uint256[] memory feeAmounts
    ) external returns (uint256[] memory);

    /// @notice Attach a module
    /// @param module a module to attach
    /// @param enabled if the module is enabled by default
    /// @param canModuleMint if the module has to be given the minter role
    function attachModule(
        address module,
        bool enabled,
        bool canModuleMint
    ) external;

    /// @dev Allows owner to enable a module
    /// @param module to enable
    /// @param canModuleMint if the module has to be given the minter role
    function enableModule(address module, bool canModuleMint) external;

    /// @dev Allows owner to disable a module
    /// @param module to disable
    function disableModule(address module, bool keepListeners) external;

    /// @notice function that returns a string that can be used to render the current token
    /// @param tokenId tokenId
    /// @return the URI to render token
    function renderTokenURI(uint256 tokenId)
        external
        view
        returns (string memory);
}

File 6 of 13 : ECDSA.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/cryptography/ECDSA.sol)

pragma solidity ^0.8.0;

import "../Strings.sol";

/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS,
        InvalidSignatureV
    }

    function _throwError(RecoverError error) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert("ECDSA: invalid signature");
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert("ECDSA: invalid signature length");
        } else if (error == RecoverError.InvalidSignatureS) {
            revert("ECDSA: invalid signature 's' value");
        } else if (error == RecoverError.InvalidSignatureV) {
            revert("ECDSA: invalid signature 'v' value");
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature` or error string. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
        // Check the signature length
        // - case 65: r,s,v signature (standard)
        // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            return tryRecover(hash, v, r, s);
        } else if (signature.length == 64) {
            bytes32 r;
            bytes32 vs;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            assembly {
                r := mload(add(signature, 0x20))
                vs := mload(add(signature, 0x40))
            }
            return tryRecover(hash, r, vs);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength);
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, signature);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address, RecoverError) {
        bytes32 s;
        uint8 v;
        assembly {
            s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            v := add(shr(255, vs), 27)
        }
        return tryRecover(hash, v, r, s);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
     *
     * _Available since v4.2._
     */
    function recover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, r, vs);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
     * `r` and `s` signature fields separately.
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address, RecoverError) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return (address(0), RecoverError.InvalidSignatureS);
        }
        if (v != 27 && v != 28) {
            return (address(0), RecoverError.InvalidSignatureV);
        }

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        if (signer == address(0)) {
            return (address(0), RecoverError.InvalidSignature);
        }

        return (signer, RecoverError.NoError);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from `s`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
    }

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
    }
}

File 7 of 13 : 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 8 of 13 : 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 9 of 13 : INFModule.sol
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import '@openzeppelin/contracts/utils/introspection/IERC165.sol';

interface INFModule is IERC165 {
    /// @notice Called by a Token Registry whenever the module is Attached
    /// @return if the attach worked
    function onAttach() external returns (bool);

    /// @notice Called by a Token Registry whenever the module is Enabled
    /// @return if the enabling worked
    function onEnable() external returns (bool);

    /// @notice Called by a Token Registry whenever the module is Disabled
    function onDisable() external;

    /// @notice returns an URI with information about the module
    /// @return the URI where to find information about the module
    function contractURI() external view returns (string memory);
}

File 10 of 13 : 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 11 of 13 : EnumerableSet.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)

pragma solidity ^0.8.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

    struct Set {
        // Storage of set values
        bytes32[] _values;
        // Position of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping(bytes32 => uint256) _indexes;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function _remove(Set storage set, bytes32 value) private returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) {
            // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;

            if (lastIndex != toDeleteIndex) {
                bytes32 lastvalue = set._values[lastIndex];

                // Move the last value to the index where the value to delete is
                set._values[toDeleteIndex] = lastvalue;
                // Update the index for the moved value
                set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex
            }

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the index for the deleted slot
            delete set._indexes[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function _contains(Set storage set, bytes32 value) private view returns (bool) {
        return set._indexes[value] != 0;
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function _length(Set storage set) private view returns (uint256) {
        return set._values.length;
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function _at(Set storage set, uint256 index) private view returns (bytes32) {
        return set._values[index];
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function _values(Set storage set) private view returns (bytes32[] memory) {
        return set._values;
    }

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _add(set._inner, value);
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _remove(set._inner, value);
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
        return _contains(set._inner, value);
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(Bytes32Set storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
        return _at(set._inner, index);
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
        return _values(set._inner);
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(AddressSet storage set, address value) internal returns (bool) {
        return _add(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(AddressSet storage set, address value) internal returns (bool) {
        return _remove(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(AddressSet storage set, address value) internal view returns (bool) {
        return _contains(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(AddressSet storage set, uint256 index) internal view returns (address) {
        return address(uint160(uint256(_at(set._inner, index))));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(AddressSet storage set) internal view returns (address[] memory) {
        bytes32[] memory store = _values(set._inner);
        address[] memory result;

        assembly {
            result := store
        }

        return result;
    }

    // UintSet

    struct UintSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(UintSet storage set, uint256 value) internal returns (bool) {
        return _remove(set._inner, bytes32(value));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(UintSet storage set, uint256 value) internal view returns (bool) {
        return _contains(set._inner, bytes32(value));
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(UintSet storage set, uint256 index) internal view returns (uint256) {
        return uint256(_at(set._inner, index));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(UintSet storage set) internal view returns (uint256[] memory) {
        bytes32[] memory store = _values(set._inner);
        uint256[] memory result;

        assembly {
            result := store
        }

        return result;
    }
}

File 12 of 13 : 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 13 of 13 : 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);
}

Settings
{
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"nftContract_","type":"address"},{"internalType":"address","name":"rendererAddress_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"LoveSender","type":"address"},{"indexed":true,"internalType":"address","name":"LoveReceiver","type":"address"}],"name":"LoveDeclared","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"contractURI","type":"string"}],"name":"NewContractURI","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"},{"inputs":[{"internalType":"address","name":"LoveReceiver","type":"address"}],"name":"DeclareMyLove","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"bonesURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"heart","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nftContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"onAttach","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"onDisable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"onEnable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rendererAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId_","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"nftContract_","type":"address"}],"name":"setNFTContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"skinURI_","type":"string"}],"name":"setSkinURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"bonesURI_","type":"string"}],"name":"setbonesURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"newPhase","type":"uint8"}],"name":"setphase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"skinURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId_","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b50604051620032a9380380620032a9833981810160405281019062000037919062000346565b60405180602001604052806000815250620000676200005b6200010b60201b60201c565b6200011360201b60201c565b6200007881620001d760201b60201c565b5081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060016007819055505050620004ba565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8060039080519060200190620001ef9291906200022c565b507fdf1280b84eee5cd4ce59294c59ec7288bd49034d7f3d142f57ba9b47791563648160405162000221919062000431565b60405180910390a150565b8280546200023a9062000484565b90600052602060002090601f0160209004810192826200025e5760008555620002aa565b82601f106200027957805160ff1916838001178555620002aa565b82800160010185558215620002aa579182015b82811115620002a95782518255916020019190600101906200028c565b5b509050620002b99190620002bd565b5090565b5b80821115620002d8576000816000905550600101620002be565b5090565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200030e82620002e1565b9050919050565b620003208162000301565b81146200032c57600080fd5b50565b600081519050620003408162000315565b92915050565b6000806040838503121562000360576200035f620002dc565b5b600062000370858286016200032f565b925050602062000383858286016200032f565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b60005b83811015620003c9578082015181840152602081019050620003ac565b83811115620003d9576000848401525b50505050565b6000601f19601f8301169050919050565b6000620003fd826200038d565b62000409818562000398565b93506200041b818560208601620003a9565b6200042681620003df565b840191505092915050565b600060208201905081810360008301526200044d8184620003f0565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200049d57607f821691505b60208210811415620004b457620004b362000455565b5b50919050565b612ddf80620004ca6000396000f3fe608060405234801561001057600080fd5b50600436106101585760003560e01c8063c87b56dd116100c3578063e9dc63751161007c578063e9dc63751461037f578063ea469b45146103af578063ed1b3144146103cb578063f2fde38b146103e9578063f58d1c9414610405578063fdf061ad1461040f57610158565b8063c87b56dd146102a8578063cef6d368146102d8578063d56d229d14610309578063d5b10e4b14610327578063d67c52eb14610343578063e8a3d4851461036157610158565b8063715018a611610115578063715018a61461020c5780637db93653146102165780638da5cb5b14610232578063a7ccabdf14610250578063b079ac901461026c578063c2d0e65f1461028a57610158565b806301ffc9a71461015d5780631249c58b1461018d57806317d70f7c146101975780632782d6c7146101b55780634c85eb1f146101e657806364b9a96d146101f0575b600080fd5b61017760048036038101906101729190612026565b61042d565b604051610184919061206e565b60405180910390f35b61019561050f565b005b61019f610685565b6040516101ac91906120a2565b60405180910390f35b6101cf60048036038101906101ca9190612147565b61068b565b6040516101dd929190612196565b60405180910390f35b6101ee6106a4565b005b61020a600480360381019061020591906121bf565b6106a6565b005b610214610703565b005b610230600480360381019061022b9190612332565b61078b565b005b61023a610821565b604051610247919061237b565b60405180910390f35b61026a600480360381019061026591906121bf565b61084a565b005b61027461090a565b604051610281919061206e565b60405180910390f35b610292610913565b60405161029f919061241e565b60405180910390f35b6102c260048036038101906102bd9190612440565b6109a1565b6040516102cf919061241e565b60405180910390f35b6102f260048036038101906102ed9190612440565b6109b4565b604051610300929190612196565b60405180910390f35b6103116109ca565b60405161031e919061237b565b60405180910390f35b610341600480360381019061033c91906124a6565b6109f0565b005b61034b610a79565b604051610358919061237b565b60405180910390f35b610369610a9f565b604051610376919061241e565b60405180910390f35b61039960048036038101906103949190612147565b610b31565b6040516103a6919061241e565b60405180910390f35b6103c960048036038101906103c49190612332565b610c7a565b005b6103d3610d10565b6040516103e0919061206e565b60405180910390f35b61040360048036038101906103fe91906121bf565b610d72565b005b61040d610e6a565b005b610417611c90565b604051610424919061241e565b60405180910390f35b60007fe97405af000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806104f857507f21a735a8000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610508575061050782611d1e565b5b9050919050565b610517611d88565b73ffffffffffffffffffffffffffffffffffffffff16610535610821565b73ffffffffffffffffffffffffffffffffffffffff161461058b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105829061251f565b60405180910390fd5b6000600854146105d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105c79061258b565b60405180910390fd5b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166361e5355d610616610821565b60008060006040518563ffffffff1660e01b815260040161063a9493929190612616565b6020604051808303816000875af1158015610659573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061067d9190612683565b600881905550565b60085481565b600080610696610821565b6101f4915091509250929050565b565b8073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fa0edd6510420df9da5d742e3fba6579b90409ee0a26b48e931cbbcc1ee1501a760405160405180910390a350565b61070b611d88565b73ffffffffffffffffffffffffffffffffffffffff16610729610821565b73ffffffffffffffffffffffffffffffffffffffff161461077f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107769061251f565b60405180910390fd5b6107896000611d90565b565b610793611d88565b73ffffffffffffffffffffffffffffffffffffffff166107b1610821565b73ffffffffffffffffffffffffffffffffffffffff1614610807576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107fe9061251f565b60405180910390fd5b806004908051906020019061081d929190611f17565b5050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b610852611d88565b73ffffffffffffffffffffffffffffffffffffffff16610870610821565b73ffffffffffffffffffffffffffffffffffffffff16146108c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108bd9061251f565b60405180910390fd5b80600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60006001905090565b60058054610920906126df565b80601f016020809104026020016040519081016040528092919081815260200182805461094c906126df565b80156109995780601f1061096e57610100808354040283529160200191610999565b820191906000526020600020905b81548152906001019060200180831161097c57829003601f168201915b505050505081565b60606109ad3383610b31565b9050919050565b6000806109c1338461068b565b91509150915091565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6109f8611d88565b73ffffffffffffffffffffffffffffffffffffffff16610a16610821565b73ffffffffffffffffffffffffffffffffffffffff1614610a6c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a639061251f565b60405180910390fd5b8060ff1660078190555050565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b606060038054610aae906126df565b80601f0160208091040260200160405190810160405280929190818152602001828054610ada906126df565b8015610b275780601f10610afc57610100808354040283529160200191610b27565b820191906000526020600020905b815481529060010190602001808311610b0a57829003601f168201915b5050505050905090565b60608060036007541415610c0c576000600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166319e00849306040518263ffffffff1660e01b8152600401610b9c919061237b565b600060405180830381865afa158015610bb9573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610be29190612781565b905080604051602001610bf5919061295c565b604051602081830303815290604052915050610c70565b60026007541415610c3f576005604051602001610c299190612b01565b6040516020818303038152906040529050610c6f565b60016007541415610c6e576004604051602001610c5c9190612c12565b60405160208183030381529060405290505b5b5b8091505092915050565b610c82611d88565b73ffffffffffffffffffffffffffffffffffffffff16610ca0610821565b73ffffffffffffffffffffffffffffffffffffffff1614610cf6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ced9061251f565b60405180910390fd5b8060059080519060200190610d0c929190611f17565b5050565b6000610d26336001611e5490919063ffffffff16565b15610d345760019050610d6f565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d6690612c8b565b60405180910390fd5b90565b610d7a611d88565b73ffffffffffffffffffffffffffffffffffffffff16610d98610821565b73ffffffffffffffffffffffffffffffffffffffff1614610dee576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610de59061251f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610e5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e5590612d1d565b60405180910390fd5b610e6781611d90565b50565b6000610eab576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ea290612d89565b60405180910390fd5b7aa00000a00000a00000ffffffffffffffffffa00000a00000a000006045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60455572ffffffffffffffffffffffffffffffffffffff6045557dff0000ff0000ff0000a00000ffffffa00000ff0000ff0000ff0000a000006045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045556dffffffffffffffffffffffffffff6045557aa00000a00000a00000ffffffffffffffffffa00000a00000a000006045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60455572ffffffffffffffffffffffffffffffffffffff6045557aa00000a00000a00000ffffffffffffffffffa00000a00000a000006045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60455572ffffffffffffffffffffffffffffffffffffff6045557aa00000a00000a00000ffffffffffffffffffa00000a00000a000006045557dffffffffffffffffffffffffffffffffffffffffffffffff000000ffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffff0000001111ff0000000fff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045556cffffffffffffffffffffffffff6045557aa00000a00000a00000ffffffffffffffffffa00000a00000a000006045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557a1110001111ff1111ff1111ff000000000abcffffffffffdfffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60455577ffffffffffffffffffffffffffffffffffffffffffffffff6045557dfffffff1100110000ff0000ff0000ff0000ff0000ff001100fffffffffff60455572ffffffffffffffffffffffffffffffffffffff6045557aa00000a00000a00000ffffffffffffffffffa00000a00000a000006045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60455566ffffffffffffff6045557d1aa1100001100ff1100ff1100ff1100ff1100ff1100ff1111ff111111fff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557bffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557d1aa1100001100ff1100ff1100ff1100ff1100ff1100ff1111ff111111fff60455572ffffffffffffffffffffffffffffffffffffff6045557aa00000a00000a00000ffffffffffffffffffa00000a00000a000006045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60455567ffffffffffffffff6045557d1aa1100001100ff1100ff1100ff1100111100ff1100ff1111ff111111fff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557daffffff110022110022110022ffffff110022110022111122fffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60455572ffffffffffffffffffffffffffffffffffffff6045557aa00000a00000a00000ffffffffffffffffffa00000a00000a000006045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60455572ffffffffffffffffffffffffffffffffffffff6045557aa00000a00000a00000ffffffffffffffffffa00000a00000a000006045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60455572ffffffffffffffffffffffffffffffffffffff6045557aa00000a00000a00000ffffffffffffffffffa00000a00000a000006045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60455572ffffffffffffffffffffffffffffffffffffff604555565b60048054611c9d906126df565b80601f0160208091040260200160405190810160405280929190818152602001828054611cc9906126df565b8015611d165780601f10611ceb57610100808354040283529160200191611d16565b820191906000526020600020905b815481529060010190602001808311611cf957829003601f168201915b505050505081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000611e7c836000018373ffffffffffffffffffffffffffffffffffffffff1660001b611e84565b905092915050565b6000611e908383611ef4565b611ee9578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611eee565b600090505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b828054611f23906126df565b90600052602060002090601f016020900481019282611f455760008555611f8c565b82601f10611f5e57805160ff1916838001178555611f8c565b82800160010185558215611f8c579182015b82811115611f8b578251825591602001919060010190611f70565b5b509050611f999190611f9d565b5090565b5b80821115611fb6576000816000905550600101611f9e565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61200381611fce565b811461200e57600080fd5b50565b60008135905061202081611ffa565b92915050565b60006020828403121561203c5761203b611fc4565b5b600061204a84828501612011565b91505092915050565b60008115159050919050565b61206881612053565b82525050565b6000602082019050612083600083018461205f565b92915050565b6000819050919050565b61209c81612089565b82525050565b60006020820190506120b76000830184612093565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006120e8826120bd565b9050919050565b6120f8816120dd565b811461210357600080fd5b50565b600081359050612115816120ef565b92915050565b61212481612089565b811461212f57600080fd5b50565b6000813590506121418161211b565b92915050565b6000806040838503121561215e5761215d611fc4565b5b600061216c85828601612106565b925050602061217d85828601612132565b9150509250929050565b612190816120dd565b82525050565b60006040820190506121ab6000830185612187565b6121b86020830184612093565b9392505050565b6000602082840312156121d5576121d4611fc4565b5b60006121e384828501612106565b91505092915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61223f826121f6565b810181811067ffffffffffffffff8211171561225e5761225d612207565b5b80604052505050565b6000612271611fba565b905061227d8282612236565b919050565b600067ffffffffffffffff82111561229d5761229c612207565b5b6122a6826121f6565b9050602081019050919050565b82818337600083830152505050565b60006122d56122d084612282565b612267565b9050828152602081018484840111156122f1576122f06121f1565b5b6122fc8482856122b3565b509392505050565b600082601f830112612319576123186121ec565b5b81356123298482602086016122c2565b91505092915050565b60006020828403121561234857612347611fc4565b5b600082013567ffffffffffffffff81111561236657612365611fc9565b5b61237284828501612304565b91505092915050565b60006020820190506123906000830184612187565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156123d05780820151818401526020810190506123b5565b838111156123df576000848401525b50505050565b60006123f082612396565b6123fa81856123a1565b935061240a8185602086016123b2565b612413816121f6565b840191505092915050565b6000602082019050818103600083015261243881846123e5565b905092915050565b60006020828403121561245657612455611fc4565b5b600061246484828501612132565b91505092915050565b600060ff82169050919050565b6124838161246d565b811461248e57600080fd5b50565b6000813590506124a08161247a565b92915050565b6000602082840312156124bc576124bb611fc4565b5b60006124ca84828501612491565b91505092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006125096020836123a1565b9150612514826124d3565b602082019050919050565b60006020820190508181036000830152612538816124fc565b9050919050565b7f416c72656164794d696e74656400000000000000000000000000000000000000600082015250565b6000612575600d836123a1565b91506125808261253f565b602082019050919050565b600060208201905081810360008301526125a481612568565b9050919050565b50565b60006125bb6000836123a1565b91506125c6826125ab565b600082019050919050565b6000819050919050565b6000819050919050565b60006126006125fb6125f6846125d1565b6125db565b612089565b9050919050565b612610816125e5565b82525050565b600060a08201905061262b6000830187612187565b818103602083015261263c816125ae565b905061264b6040830186612187565b6126586060830185612607565b6126656080830184612187565b95945050505050565b60008151905061267d8161211b565b92915050565b60006020828403121561269957612698611fc4565b5b60006126a78482850161266e565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806126f757607f821691505b6020821081141561270b5761270a6126b0565b5b50919050565b600061272461271f84612282565b612267565b9050828152602081018484840111156127405761273f6121f1565b5b61274b8482856123b2565b509392505050565b600082601f830112612768576127676121ec565b5b8151612778848260208601612711565b91505092915050565b60006020828403121561279757612796611fc4565b5b600082015167ffffffffffffffff8111156127b5576127b4611fc9565b5b6127c184828501612753565b91505092915050565b600081905092915050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b757466382c7b2264657360008201527f6372697074696f6e223a22e29da4efb88f222c226e616d65223a22416e61746f60208201527f6d79204f66204c6f7665222c2261747472696275746573223a5b7b227472616960408201527f745f74797065223a225068617365222c2276616c7565223a22546865204d696e60608201527f64227d5d2c22696d616765223a22646174613a696d6167652f7376672b786d6c60808201527f3b6261736536342c00000000000000000000000000000000000000000000000060a082015250565b60006128c960a8836127ca565b91506128d4826127d5565b60a882019050919050565b60006128ea82612396565b6128f481856127ca565b93506129048185602086016123b2565b80840191505092915050565b7f227d000000000000000000000000000000000000000000000000000000000000600082015250565b60006129466002836127ca565b915061295182612910565b600282019050919050565b6000612967826128bc565b915061297382846128df565b915061297e82612939565b915081905092915050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b757466382c7b2264657360008201527f6372697074696f6e223a22e29da4efb88f222c226e616d65223a22416e61746f60208201527f6d79204f66204c6f7665222c2261747472696275746573223a5b7b227472616960408201527f745f74797065223a225068617365222c2276616c7565223a2254686520426f6e60608201527f6573227d5d2c22616e696d6174696f6e5f75726c223a22000000000000000000608082015250565b6000612a576097836127ca565b9150612a6282612989565b609782019050919050565b60008190508160005260206000209050919050565b60008154612a8f816126df565b612a9981866127ca565b94506001821660008114612ab45760018114612ac557612af8565b60ff19831686528186019350612af8565b612ace85612a6d565b60005b83811015612af057815481890152600182019150602081019050612ad1565b838801955050505b50505092915050565b6000612b0c82612a4a565b9150612b188284612a82565b9150612b2382612939565b915081905092915050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b757466382c7b2264657360008201527f6372697074696f6e223a22e29da4efb88f222c226e616d65223a22416e61746f60208201527f6d79204f66204c6f7665222c2261747472696275746573223a5b7b227472616960408201527f745f74797065223a225068617365222c2276616c7565223a2254686520536b6960608201527f6e227d5d2c22696d616765223a22000000000000000000000000000000000000608082015250565b6000612bfc608e836127ca565b9150612c0782612b2e565b608e82019050919050565b6000612c1d82612bef565b9150612c298284612a82565b9150612c3482612939565b915081905092915050565b7f21414c52454144595f4154544143484544210000000000000000000000000000600082015250565b6000612c756012836123a1565b9150612c8082612c3f565b602082019050919050565b60006020820190508181036000830152612ca481612c68565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000612d076026836123a1565b9150612d1282612cab565b604082019050919050565b60006020820190508181036000830152612d3681612cfa565b9050919050565b7f6e6f706500000000000000000000000000000000000000000000000000000000600082015250565b6000612d736004836123a1565b9150612d7e82612d3d565b602082019050919050565b60006020820190508181036000830152612da281612d66565b905091905056fea2646970667358221220160e471dd5af65b5a3968b5fa42f9670daef61ffb26d47e2c8b22dcbaa55bf9e64736f6c634300080b0033000000000000000000000000ab088f80f425ceafdb950c1b5d50f8d59382377800000000000000000000000017dbcb356318b08783ac5837690bb91939b107dd

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101585760003560e01c8063c87b56dd116100c3578063e9dc63751161007c578063e9dc63751461037f578063ea469b45146103af578063ed1b3144146103cb578063f2fde38b146103e9578063f58d1c9414610405578063fdf061ad1461040f57610158565b8063c87b56dd146102a8578063cef6d368146102d8578063d56d229d14610309578063d5b10e4b14610327578063d67c52eb14610343578063e8a3d4851461036157610158565b8063715018a611610115578063715018a61461020c5780637db93653146102165780638da5cb5b14610232578063a7ccabdf14610250578063b079ac901461026c578063c2d0e65f1461028a57610158565b806301ffc9a71461015d5780631249c58b1461018d57806317d70f7c146101975780632782d6c7146101b55780634c85eb1f146101e657806364b9a96d146101f0575b600080fd5b61017760048036038101906101729190612026565b61042d565b604051610184919061206e565b60405180910390f35b61019561050f565b005b61019f610685565b6040516101ac91906120a2565b60405180910390f35b6101cf60048036038101906101ca9190612147565b61068b565b6040516101dd929190612196565b60405180910390f35b6101ee6106a4565b005b61020a600480360381019061020591906121bf565b6106a6565b005b610214610703565b005b610230600480360381019061022b9190612332565b61078b565b005b61023a610821565b604051610247919061237b565b60405180910390f35b61026a600480360381019061026591906121bf565b61084a565b005b61027461090a565b604051610281919061206e565b60405180910390f35b610292610913565b60405161029f919061241e565b60405180910390f35b6102c260048036038101906102bd9190612440565b6109a1565b6040516102cf919061241e565b60405180910390f35b6102f260048036038101906102ed9190612440565b6109b4565b604051610300929190612196565b60405180910390f35b6103116109ca565b60405161031e919061237b565b60405180910390f35b610341600480360381019061033c91906124a6565b6109f0565b005b61034b610a79565b604051610358919061237b565b60405180910390f35b610369610a9f565b604051610376919061241e565b60405180910390f35b61039960048036038101906103949190612147565b610b31565b6040516103a6919061241e565b60405180910390f35b6103c960048036038101906103c49190612332565b610c7a565b005b6103d3610d10565b6040516103e0919061206e565b60405180910390f35b61040360048036038101906103fe91906121bf565b610d72565b005b61040d610e6a565b005b610417611c90565b604051610424919061241e565b60405180910390f35b60007fe97405af000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806104f857507f21a735a8000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610508575061050782611d1e565b5b9050919050565b610517611d88565b73ffffffffffffffffffffffffffffffffffffffff16610535610821565b73ffffffffffffffffffffffffffffffffffffffff161461058b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105829061251f565b60405180910390fd5b6000600854146105d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105c79061258b565b60405180910390fd5b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166361e5355d610616610821565b60008060006040518563ffffffff1660e01b815260040161063a9493929190612616565b6020604051808303816000875af1158015610659573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061067d9190612683565b600881905550565b60085481565b600080610696610821565b6101f4915091509250929050565b565b8073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fa0edd6510420df9da5d742e3fba6579b90409ee0a26b48e931cbbcc1ee1501a760405160405180910390a350565b61070b611d88565b73ffffffffffffffffffffffffffffffffffffffff16610729610821565b73ffffffffffffffffffffffffffffffffffffffff161461077f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107769061251f565b60405180910390fd5b6107896000611d90565b565b610793611d88565b73ffffffffffffffffffffffffffffffffffffffff166107b1610821565b73ffffffffffffffffffffffffffffffffffffffff1614610807576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107fe9061251f565b60405180910390fd5b806004908051906020019061081d929190611f17565b5050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b610852611d88565b73ffffffffffffffffffffffffffffffffffffffff16610870610821565b73ffffffffffffffffffffffffffffffffffffffff16146108c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108bd9061251f565b60405180910390fd5b80600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60006001905090565b60058054610920906126df565b80601f016020809104026020016040519081016040528092919081815260200182805461094c906126df565b80156109995780601f1061096e57610100808354040283529160200191610999565b820191906000526020600020905b81548152906001019060200180831161097c57829003601f168201915b505050505081565b60606109ad3383610b31565b9050919050565b6000806109c1338461068b565b91509150915091565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6109f8611d88565b73ffffffffffffffffffffffffffffffffffffffff16610a16610821565b73ffffffffffffffffffffffffffffffffffffffff1614610a6c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a639061251f565b60405180910390fd5b8060ff1660078190555050565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b606060038054610aae906126df565b80601f0160208091040260200160405190810160405280929190818152602001828054610ada906126df565b8015610b275780601f10610afc57610100808354040283529160200191610b27565b820191906000526020600020905b815481529060010190602001808311610b0a57829003601f168201915b5050505050905090565b60608060036007541415610c0c576000600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166319e00849306040518263ffffffff1660e01b8152600401610b9c919061237b565b600060405180830381865afa158015610bb9573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610be29190612781565b905080604051602001610bf5919061295c565b604051602081830303815290604052915050610c70565b60026007541415610c3f576005604051602001610c299190612b01565b6040516020818303038152906040529050610c6f565b60016007541415610c6e576004604051602001610c5c9190612c12565b60405160208183030381529060405290505b5b5b8091505092915050565b610c82611d88565b73ffffffffffffffffffffffffffffffffffffffff16610ca0610821565b73ffffffffffffffffffffffffffffffffffffffff1614610cf6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ced9061251f565b60405180910390fd5b8060059080519060200190610d0c929190611f17565b5050565b6000610d26336001611e5490919063ffffffff16565b15610d345760019050610d6f565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d6690612c8b565b60405180910390fd5b90565b610d7a611d88565b73ffffffffffffffffffffffffffffffffffffffff16610d98610821565b73ffffffffffffffffffffffffffffffffffffffff1614610dee576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610de59061251f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610e5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e5590612d1d565b60405180910390fd5b610e6781611d90565b50565b6000610eab576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ea290612d89565b60405180910390fd5b7aa00000a00000a00000ffffffffffffffffffa00000a00000a000006045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60455572ffffffffffffffffffffffffffffffffffffff6045557dff0000ff0000ff0000a00000ffffffa00000ff0000ff0000ff0000a000006045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045556dffffffffffffffffffffffffffff6045557aa00000a00000a00000ffffffffffffffffffa00000a00000a000006045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60455572ffffffffffffffffffffffffffffffffffffff6045557aa00000a00000a00000ffffffffffffffffffa00000a00000a000006045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60455572ffffffffffffffffffffffffffffffffffffff6045557aa00000a00000a00000ffffffffffffffffffa00000a00000a000006045557dffffffffffffffffffffffffffffffffffffffffffffffff000000ffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffff0000001111ff0000000fff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045556cffffffffffffffffffffffffff6045557aa00000a00000a00000ffffffffffffffffffa00000a00000a000006045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557a1110001111ff1111ff1111ff000000000abcffffffffffdfffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60455577ffffffffffffffffffffffffffffffffffffffffffffffff6045557dfffffff1100110000ff0000ff0000ff0000ff0000ff001100fffffffffff60455572ffffffffffffffffffffffffffffffffffffff6045557aa00000a00000a00000ffffffffffffffffffa00000a00000a000006045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60455566ffffffffffffff6045557d1aa1100001100ff1100ff1100ff1100ff1100ff1100ff1111ff111111fff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557bffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557d1aa1100001100ff1100ff1100ff1100ff1100ff1100ff1111ff111111fff60455572ffffffffffffffffffffffffffffffffffffff6045557aa00000a00000a00000ffffffffffffffffffa00000a00000a000006045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60455567ffffffffffffffff6045557d1aa1100001100ff1100ff1100ff1100111100ff1100ff1111ff111111fff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557daffffff110022110022110022ffffff110022110022111122fffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60455572ffffffffffffffffffffffffffffffffffffff6045557aa00000a00000a00000ffffffffffffffffffa00000a00000a000006045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60455572ffffffffffffffffffffffffffffffffffffff6045557aa00000a00000a00000ffffffffffffffffffa00000a00000a000006045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60455572ffffffffffffffffffffffffffffffffffffff6045557aa00000a00000a00000ffffffffffffffffffa00000a00000a000006045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6045557dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60455572ffffffffffffffffffffffffffffffffffffff604555565b60048054611c9d906126df565b80601f0160208091040260200160405190810160405280929190818152602001828054611cc9906126df565b8015611d165780601f10611ceb57610100808354040283529160200191611d16565b820191906000526020600020905b815481529060010190602001808311611cf957829003601f168201915b505050505081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000611e7c836000018373ffffffffffffffffffffffffffffffffffffffff1660001b611e84565b905092915050565b6000611e908383611ef4565b611ee9578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611eee565b600090505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b828054611f23906126df565b90600052602060002090601f016020900481019282611f455760008555611f8c565b82601f10611f5e57805160ff1916838001178555611f8c565b82800160010185558215611f8c579182015b82811115611f8b578251825591602001919060010190611f70565b5b509050611f999190611f9d565b5090565b5b80821115611fb6576000816000905550600101611f9e565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61200381611fce565b811461200e57600080fd5b50565b60008135905061202081611ffa565b92915050565b60006020828403121561203c5761203b611fc4565b5b600061204a84828501612011565b91505092915050565b60008115159050919050565b61206881612053565b82525050565b6000602082019050612083600083018461205f565b92915050565b6000819050919050565b61209c81612089565b82525050565b60006020820190506120b76000830184612093565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006120e8826120bd565b9050919050565b6120f8816120dd565b811461210357600080fd5b50565b600081359050612115816120ef565b92915050565b61212481612089565b811461212f57600080fd5b50565b6000813590506121418161211b565b92915050565b6000806040838503121561215e5761215d611fc4565b5b600061216c85828601612106565b925050602061217d85828601612132565b9150509250929050565b612190816120dd565b82525050565b60006040820190506121ab6000830185612187565b6121b86020830184612093565b9392505050565b6000602082840312156121d5576121d4611fc4565b5b60006121e384828501612106565b91505092915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61223f826121f6565b810181811067ffffffffffffffff8211171561225e5761225d612207565b5b80604052505050565b6000612271611fba565b905061227d8282612236565b919050565b600067ffffffffffffffff82111561229d5761229c612207565b5b6122a6826121f6565b9050602081019050919050565b82818337600083830152505050565b60006122d56122d084612282565b612267565b9050828152602081018484840111156122f1576122f06121f1565b5b6122fc8482856122b3565b509392505050565b600082601f830112612319576123186121ec565b5b81356123298482602086016122c2565b91505092915050565b60006020828403121561234857612347611fc4565b5b600082013567ffffffffffffffff81111561236657612365611fc9565b5b61237284828501612304565b91505092915050565b60006020820190506123906000830184612187565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156123d05780820151818401526020810190506123b5565b838111156123df576000848401525b50505050565b60006123f082612396565b6123fa81856123a1565b935061240a8185602086016123b2565b612413816121f6565b840191505092915050565b6000602082019050818103600083015261243881846123e5565b905092915050565b60006020828403121561245657612455611fc4565b5b600061246484828501612132565b91505092915050565b600060ff82169050919050565b6124838161246d565b811461248e57600080fd5b50565b6000813590506124a08161247a565b92915050565b6000602082840312156124bc576124bb611fc4565b5b60006124ca84828501612491565b91505092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006125096020836123a1565b9150612514826124d3565b602082019050919050565b60006020820190508181036000830152612538816124fc565b9050919050565b7f416c72656164794d696e74656400000000000000000000000000000000000000600082015250565b6000612575600d836123a1565b91506125808261253f565b602082019050919050565b600060208201905081810360008301526125a481612568565b9050919050565b50565b60006125bb6000836123a1565b91506125c6826125ab565b600082019050919050565b6000819050919050565b6000819050919050565b60006126006125fb6125f6846125d1565b6125db565b612089565b9050919050565b612610816125e5565b82525050565b600060a08201905061262b6000830187612187565b818103602083015261263c816125ae565b905061264b6040830186612187565b6126586060830185612607565b6126656080830184612187565b95945050505050565b60008151905061267d8161211b565b92915050565b60006020828403121561269957612698611fc4565b5b60006126a78482850161266e565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806126f757607f821691505b6020821081141561270b5761270a6126b0565b5b50919050565b600061272461271f84612282565b612267565b9050828152602081018484840111156127405761273f6121f1565b5b61274b8482856123b2565b509392505050565b600082601f830112612768576127676121ec565b5b8151612778848260208601612711565b91505092915050565b60006020828403121561279757612796611fc4565b5b600082015167ffffffffffffffff8111156127b5576127b4611fc9565b5b6127c184828501612753565b91505092915050565b600081905092915050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b757466382c7b2264657360008201527f6372697074696f6e223a22e29da4efb88f222c226e616d65223a22416e61746f60208201527f6d79204f66204c6f7665222c2261747472696275746573223a5b7b227472616960408201527f745f74797065223a225068617365222c2276616c7565223a22546865204d696e60608201527f64227d5d2c22696d616765223a22646174613a696d6167652f7376672b786d6c60808201527f3b6261736536342c00000000000000000000000000000000000000000000000060a082015250565b60006128c960a8836127ca565b91506128d4826127d5565b60a882019050919050565b60006128ea82612396565b6128f481856127ca565b93506129048185602086016123b2565b80840191505092915050565b7f227d000000000000000000000000000000000000000000000000000000000000600082015250565b60006129466002836127ca565b915061295182612910565b600282019050919050565b6000612967826128bc565b915061297382846128df565b915061297e82612939565b915081905092915050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b757466382c7b2264657360008201527f6372697074696f6e223a22e29da4efb88f222c226e616d65223a22416e61746f60208201527f6d79204f66204c6f7665222c2261747472696275746573223a5b7b227472616960408201527f745f74797065223a225068617365222c2276616c7565223a2254686520426f6e60608201527f6573227d5d2c22616e696d6174696f6e5f75726c223a22000000000000000000608082015250565b6000612a576097836127ca565b9150612a6282612989565b609782019050919050565b60008190508160005260206000209050919050565b60008154612a8f816126df565b612a9981866127ca565b94506001821660008114612ab45760018114612ac557612af8565b60ff19831686528186019350612af8565b612ace85612a6d565b60005b83811015612af057815481890152600182019150602081019050612ad1565b838801955050505b50505092915050565b6000612b0c82612a4a565b9150612b188284612a82565b9150612b2382612939565b915081905092915050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b757466382c7b2264657360008201527f6372697074696f6e223a22e29da4efb88f222c226e616d65223a22416e61746f60208201527f6d79204f66204c6f7665222c2261747472696275746573223a5b7b227472616960408201527f745f74797065223a225068617365222c2276616c7565223a2254686520536b6960608201527f6e227d5d2c22696d616765223a22000000000000000000000000000000000000608082015250565b6000612bfc608e836127ca565b9150612c0782612b2e565b608e82019050919050565b6000612c1d82612bef565b9150612c298284612a82565b9150612c3482612939565b915081905092915050565b7f21414c52454144595f4154544143484544210000000000000000000000000000600082015250565b6000612c756012836123a1565b9150612c8082612c3f565b602082019050919050565b60006020820190508181036000830152612ca481612c68565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000612d076026836123a1565b9150612d1282612cab565b604082019050919050565b60006020820190508181036000830152612d3681612cfa565b9050919050565b7f6e6f706500000000000000000000000000000000000000000000000000000000600082015250565b6000612d736004836123a1565b9150612d7e82612d3d565b602082019050919050565b60006020820190508181036000830152612da281612d66565b905091905056fea2646970667358221220160e471dd5af65b5a3968b5fa42f9670daef61ffb26d47e2c8b22dcbaa55bf9e64736f6c634300080b0033

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

000000000000000000000000ab088f80f425ceafdb950c1b5d50f8d59382377800000000000000000000000017dbcb356318b08783ac5837690bb91939b107dd

-----Decoded View---------------
Arg [0] : nftContract_ (address): 0xab088F80F425ceAfdb950c1B5d50F8d593823778
Arg [1] : rendererAddress_ (address): 0x17dbcb356318B08783AC5837690bB91939B107DD

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000ab088f80f425ceafdb950c1b5d50f8d593823778
Arg [1] : 00000000000000000000000017dbcb356318b08783ac5837690bb91939b107dd


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.