ETH Price: $1,822.54 (-2.42%)

Contract

0x7eeb4746d7cF45B864550C9e540aaCdbF1B9884A
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Transfer From194021922024-03-10 4:04:23389 days ago1710043463IN
0x7eeb4746...bF1B9884A
0 ETH0.0058221147.89068711
Set Approval For...190461762024-01-20 6:07:23439 days ago1705730843IN
0x7eeb4746...bF1B9884A
0 ETH0.0010468315.66858898
Set Approval For...181014972023-09-09 21:24:35571 days ago1694294675IN
0x7eeb4746...bF1B9884A
0 ETH0.000891113.33776032
Set Approval For...180646892023-09-04 17:44:47576 days ago1693849487IN
0x7eeb4746...bF1B9884A
0 ETH0.0010029415.01167252
Revoke Mint Oper...180291722023-08-30 18:23:11581 days ago1693419791IN
0x7eeb4746...bF1B9884A
0 ETH0.0009008523.78001922
Revoke Terms Ope...180291692023-08-30 18:22:35581 days ago1693419755IN
0x7eeb4746...bF1B9884A
0 ETH0.0009721725.69184985
Revoke Terms Ope...180291592023-08-30 18:20:35581 days ago1693419635IN
0x7eeb4746...bF1B9884A
0 ETH0.0008358325.13930282
Set Terms Operat...180291442023-08-30 18:17:35581 days ago1693419455IN
0x7eeb4746...bF1B9884A
0 ETH0.0009880729.49289065
Withdraw180291322023-08-30 18:15:11581 days ago1693419311IN
0x7eeb4746...bF1B9884A
0 ETH0.0011360225.66652105
Bulk Assign Rand...180235982023-08-29 23:38:59582 days ago1693352339IN
0x7eeb4746...bF1B9884A
0 ETH0.0990280924.81580701
Bulk Assign Rand...180235972023-08-29 23:38:47582 days ago1693352327IN
0x7eeb4746...bF1B9884A
0 ETH0.1333958824.86790887
Bulk Assign Rand...180235962023-08-29 23:38:35582 days ago1693352315IN
0x7eeb4746...bF1B9884A
0 ETH0.1399449125.2333507
Bulk Assign Rand...180235952023-08-29 23:38:23582 days ago1693352303IN
0x7eeb4746...bF1B9884A
0 ETH0.1388633325.04481606
Bulk Assign Rand...180235942023-08-29 23:38:11582 days ago1693352291IN
0x7eeb4746...bF1B9884A
0 ETH0.1278776324.08111929
Bulk Assign Rand...180235932023-08-29 23:37:59582 days ago1693352279IN
0x7eeb4746...bF1B9884A
0 ETH0.1380293124.36994397
Bulk Assign Rand...180235922023-08-29 23:37:47582 days ago1693352267IN
0x7eeb4746...bF1B9884A
0 ETH0.1332261624.19283516
Bulk Assign Rand...180235912023-08-29 23:37:35582 days ago1693352255IN
0x7eeb4746...bF1B9884A
0 ETH0.1359799824.02775859
Bulk Assign Rand...180235902023-08-29 23:37:23582 days ago1693352243IN
0x7eeb4746...bF1B9884A
0 ETH0.1330906423.50762727
Bulk Assign Rand...180235892023-08-29 23:37:11582 days ago1693352231IN
0x7eeb4746...bF1B9884A
0 ETH0.1252958422.34149609
Calculate Final ...180235172023-08-29 23:22:35582 days ago1693351355IN
0x7eeb4746...bF1B9884A
0 ETH0.0244510225.78210588
Calculate Final ...180235162023-08-29 23:22:23582 days ago1693351343IN
0x7eeb4746...bF1B9884A
0 ETH0.0235626324.28581561
Calculate Final ...180235162023-08-29 23:22:23582 days ago1693351343IN
0x7eeb4746...bF1B9884A
0 ETH0.0230319824.28581561
Calculate Final ...180235162023-08-29 23:22:23582 days ago1693351343IN
0x7eeb4746...bF1B9884A
0 ETH0.0230165424.28581561
Calculate Final ...180235152023-08-29 23:22:11582 days ago1693351331IN
0x7eeb4746...bF1B9884A
0 ETH0.0229210723.64206324
Convert Ticket T...180205902023-08-29 13:32:23582 days ago1693315943IN
0x7eeb4746...bF1B9884A
0.24 ETH0.0031933220.34856477
View all transactions

Latest 4 internal transactions

Advanced mode:
Parent Transaction Hash Method Block
From
To
Transfer180291322023-08-30 18:15:11581 days ago1693419311
0x7eeb4746...bF1B9884A
0.48 ETH
Transfer180172732023-08-29 2:21:11583 days ago1693275671
0x7eeb4746...bF1B9884A
128.4 ETH
Transfer180139792023-08-28 15:17:23583 days ago1693235843
0x7eeb4746...bF1B9884A
2.5 ETH
Transfer180104682023-08-28 3:30:23584 days ago1693193423
0x7eeb4746...bF1B9884A
0.001 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
KeepersDiamond

Compiler Version
v0.8.18+commit.87f61d96

Optimization Enabled:
Yes with 800 runs

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

/*                                                                                                                                                                                                                                                                            
                                       ..';;::::::;;;::::;,'.                                       
                                   .,;;;;;,'....     ....';;;;;;'.                                  
                                ';;;,..                       .';;:,.                               
                             .,;,.                                .';;'                             
                           .,;.                  ...                 .,;.                           
                          .;.                                          .;;.                         
                         ',.                                             ';.                        
                        ''                                                .,.                       
                       .'                                                  .,                       
                      .'.                      .....                        ..                      
                      ..                    .;;,,,;,,;,.                     ..                     
                     ..                    ;c'       .;c'                    ..                     
                     ..                   ;c.          'c.                    .                     
                     .                .',;dl.         .;dl,,'.                ..                    
                     .              ,:;,..:xc:,.    .;:od,.',;;.               .                    
                    .             .:c.     ,c:cc.  ,l:::.     'c'              .                    
                    .             ,l.       .,:docldl;'        ,c.                                  
                                  ,c.        ';ddldxl,.        ,c.                                  
                                  .::.     '::lo' .;oc:;.     .c'                                   
                                   .,:,...;dc::.    '::do...';:.                                    
                                      ':clkd,.        .cxdlc;.                                      
                                    .,;,,,od:;.     .,;ldc,,;;'                                     
                                   ,c,.   .:c:c,   .:::c,    .:c.                                   
                                  'l.       ,;cxc;:do:;.       ;c.                                  
                                  ,c.        .;xkxOkl.         ,c.                                  
                                  .c,      .;:lx:';od::'      .c:                                   
                                   .:;.   .lc;c,   .:::l;   .,c;                                    
                                     .,;;:do;,.      .;cxl;;;,.                                     
                                     ';;;:do;'.      .,cxl;;;,.                                     
                                   .:;.   'oc::'   .;::o:.  .,c;.                                   
                                  .l'      .::ld;.,ld::,      .c;                                   
                                  ;c.        .:xkxOko'         ,c.                                  
                                  .l'      .,;cxc;cdo:;.      .c:                                   
                                   'c;.   .cc;c;   .c::l,    'c;.                                   
                                    .';;,;od:,.     .,;lxc,;;;.                                     
                                        .'l:           .o:..                                        
                                          'l'         .::.                                          
                                           .:;'......,:;.                                           
                                             .,;,,,,,'.                                             
                                                                                                    
                                                                                                    
                                 ..                              ...                                
                                  .''.                        .''..                                 
                                    ',,'.                  ..,,,.    ......                         
                                  ..,;:c;''...        .....'..          ...':c'                     
                               .;:;;'.    ................                 .:Kx.                    
                            .:lc,.                                   ..';:cokd'                     
                           ;xo.                                 ..,:ldkkOOxo,                       
                          ;0l                            ...',:oxO0KXK0xl;.                         
                          ;0x'   ................''',;:lodkOKXNWNX0ko:'.                            
                           ,oxdoccclodxxxkkkOO00KKXXXNWWWWWNK0xoc;..                                
                             .':lloodxkO00KKKKKK0OOOkxdoc:;'..                                      
                                    ................                                                                                                                                                                       
*/

pragma solidity 0.8.18;

import { SolidStateDiamondRevokableUpgradability } from "./SolidStateDiamondRevokableUpgradability.sol";
import { AccessControlInternal } from "@solidstate/contracts/access/access_control/AccessControlInternal.sol";
import { IERC721 } from "@solidstate/contracts/interfaces/IERC721.sol";
import { IERC165 } from "@solidstate/contracts/interfaces/IERC165.sol";
import { IERC2981 } from "@solidstate/contracts/interfaces/IERC2981.sol";
import { IERC721Enumerable } from "@solidstate/contracts/token/ERC721/enumerable/IERC721Enumerable.sol";
import { ERC2981Storage } from "@solidstate/contracts/token/common/ERC2981/ERC2981Storage.sol";
import { KeepersERC721Storage } from "./facets/KeepersERC721/KeepersERC721Storage.sol";
import { ERC721MetadataStorage } from "@solidstate/contracts/token/ERC721/metadata/ERC721MetadataStorage.sol";
import { TermsStorage } from "./facets/Terms/TermsStorage.sol";
import { ConstantsLib } from "./library/ConstantsLib.sol";
import { DiamondWritableInternal } from "@solidstate/contracts/proxy/diamond/writable/DiamondWritableInternal.sol";
import { CANONICAL_CORI_SUBSCRIPTION } from "operator-filter-registry/src/lib/Constants.sol";
import { DiamondOperatorFilter } from "./DiamondOperatorFilter.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

/**
 * @title KeepersDiamond "Diamond" proxy implementation based on SolidState Diamond Reference
 */
contract KeepersDiamond is SolidStateDiamondRevokableUpgradability, AccessControlInternal, DiamondOperatorFilter {
    using Counters for Counters.Counter;

    constructor(string memory name_, string memory symbol_, string memory baseURI_) {
        // ERC165 - note: other interfaces are set in SolidStateDiamondRevokableUpgradability
        _setSupportsInterface(type(IERC721).interfaceId, true);
        _setSupportsInterface(type(IERC721Enumerable).interfaceId, true);
        _setSupportsInterface(type(IERC2981).interfaceId, true);

        // AccessControl
        _grantRole(ConstantsLib.KEEPERS_TERMS_OPERATOR, msg.sender);
        _grantRole(ConstantsLib.KEEPERS_LICENSE_OPERATOR, msg.sender);

        // ERC2981
        ERC2981Storage.layout().defaultRoyaltyBPS = 700; // 7%
        ERC2981Storage.layout().defaultRoyaltyReceiver = msg.sender;

        // mint parameters
        KeepersERC721Storage.layout().maxPerAddress = 10;
        KeepersERC721Storage.layout().numAvailableTokens = uint16(ConstantsLib.MAX_TICKETS);

        // Metadata
        ERC721MetadataStorage.layout().name = name_;
        ERC721MetadataStorage.layout().symbol = symbol_;
        ERC721MetadataStorage.layout().baseURI = baseURI_;

        // Terms version
        TermsStorage.layout().termsVersion.increment(); // Set terms to V1 by default

        // Set up Operator Filter Registry
        __OperatorFilterer_init(CANONICAL_CORI_SUBSCRIPTION);
    }
}

File 2 of 57 : Counters.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)

pragma solidity ^0.8.0;

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 */
library Counters {
    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        unchecked {
            counter._value += 1;
        }
    }

    function decrement(Counter storage counter) internal {
        uint256 value = counter._value;
        require(value > 0, "Counter: decrement overflow");
        unchecked {
            counter._value = value - 1;
        }
    }

    function reset(Counter storage counter) internal {
        counter._value = 0;
    }
}

File 3 of 57 : AccessControlInternal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { EnumerableSet } from '../../data/EnumerableSet.sol';
import { AddressUtils } from '../../utils/AddressUtils.sol';
import { UintUtils } from '../../utils/UintUtils.sol';
import { IAccessControlInternal } from './IAccessControlInternal.sol';
import { AccessControlStorage } from './AccessControlStorage.sol';

/**
 * @title Role-based access control system
 * @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts (MIT license)
 */
abstract contract AccessControlInternal is IAccessControlInternal {
    using AddressUtils for address;
    using EnumerableSet for EnumerableSet.AddressSet;
    using UintUtils for uint256;

    modifier onlyRole(bytes32 role) {
        _checkRole(role);
        _;
    }

    /*
     * @notice query whether role is assigned to account
     * @param role role to query
     * @param account account to query
     * @return whether role is assigned to account
     */
    function _hasRole(
        bytes32 role,
        address account
    ) internal view virtual returns (bool) {
        return
            AccessControlStorage.layout().roles[role].members.contains(account);
    }

    /**
     * @notice revert if sender does not have given role
     * @param role role to query
     */
    function _checkRole(bytes32 role) internal view virtual {
        _checkRole(role, msg.sender);
    }

    /**
     * @notice revert if given account does not have given role
     * @param role role to query
     * @param account to query
     */
    function _checkRole(bytes32 role, address account) internal view virtual {
        if (!_hasRole(role, account)) {
            revert(
                string(
                    abi.encodePacked(
                        'AccessControl: account ',
                        account.toString(),
                        ' is missing role ',
                        uint256(role).toHexString(32)
                    )
                )
            );
        }
    }

    /*
     * @notice query admin role for given role
     * @param role role to query
     * @return admin role
     */
    function _getRoleAdmin(
        bytes32 role
    ) internal view virtual returns (bytes32) {
        return AccessControlStorage.layout().roles[role].adminRole;
    }

    /**
     * @notice set role as admin role
     * @param role role to set
     * @param adminRole admin role to set
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        bytes32 previousAdminRole = _getRoleAdmin(role);
        AccessControlStorage.layout().roles[role].adminRole = adminRole;
        emit RoleAdminChanged(role, previousAdminRole, adminRole);
    }

    /*
     * @notice assign role to given account
     * @param role role to assign
     * @param account recipient of role assignment
     */
    function _grantRole(bytes32 role, address account) internal virtual {
        AccessControlStorage.layout().roles[role].members.add(account);
        emit RoleGranted(role, account, msg.sender);
    }

    /*
     * @notice unassign role from given account
     * @param role role to unassign
     * @parm account
     */
    function _revokeRole(bytes32 role, address account) internal virtual {
        AccessControlStorage.layout().roles[role].members.remove(account);
        emit RoleRevoked(role, account, msg.sender);
    }

    /**
     * @notice relinquish role
     * @param role role to relinquish
     */
    function _renounceRole(bytes32 role) internal virtual {
        _revokeRole(role, msg.sender);
    }
}

File 4 of 57 : AccessControlStorage.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { EnumerableSet } from '../../data/EnumerableSet.sol';

library AccessControlStorage {
    struct RoleData {
        EnumerableSet.AddressSet members;
        bytes32 adminRole;
    }

    struct Layout {
        mapping(bytes32 => RoleData) roles;
    }

    bytes32 internal constant DEFAULT_ADMIN_ROLE = 0x00;

    bytes32 internal constant STORAGE_SLOT =
        keccak256('solidstate.contracts.storage.AccessControl');

    function layout() internal pure returns (Layout storage l) {
        bytes32 slot = STORAGE_SLOT;
        assembly {
            l.slot := slot
        }
    }
}

File 5 of 57 : IAccessControlInternal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @title Partial AccessControl interface needed by internal functions
 */
interface IAccessControlInternal {
    event RoleAdminChanged(
        bytes32 indexed role,
        bytes32 indexed previousAdminRole,
        bytes32 indexed newAdminRole
    );

    event RoleGranted(
        bytes32 indexed role,
        address indexed account,
        address indexed sender
    );

    event RoleRevoked(
        bytes32 indexed role,
        address indexed account,
        address indexed sender
    );
}

File 6 of 57 : IOwnable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IERC173 } from '../../interfaces/IERC173.sol';
import { IOwnableInternal } from './IOwnableInternal.sol';

interface IOwnable is IOwnableInternal, IERC173 {}

File 7 of 57 : IOwnableInternal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IERC173Internal } from '../../interfaces/IERC173Internal.sol';

interface IOwnableInternal is IERC173Internal {
    error Ownable__NotOwner();
    error Ownable__NotTransitiveOwner();
}

File 8 of 57 : ISafeOwnable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IOwnable } from './IOwnable.sol';
import { ISafeOwnableInternal } from './ISafeOwnableInternal.sol';

interface ISafeOwnable is ISafeOwnableInternal, IOwnable {
    /**
     * @notice get the nominated owner who has permission to call acceptOwnership
     */
    function nomineeOwner() external view returns (address);

    /**
     * @notice accept transfer of contract ownership
     */
    function acceptOwnership() external;
}

File 9 of 57 : ISafeOwnableInternal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IOwnableInternal } from './IOwnableInternal.sol';

interface ISafeOwnableInternal is IOwnableInternal {
    error SafeOwnable__NotNomineeOwner();
}

File 10 of 57 : Ownable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IERC173 } from '../../interfaces/IERC173.sol';
import { IOwnable } from './IOwnable.sol';
import { OwnableInternal } from './OwnableInternal.sol';

/**
 * @title Ownership access control based on ERC173
 */
abstract contract Ownable is IOwnable, OwnableInternal {
    /**
     * @inheritdoc IERC173
     */
    function owner() public view virtual returns (address) {
        return _owner();
    }

    /**
     * @inheritdoc IERC173
     */
    function transferOwnership(address account) public virtual onlyOwner {
        _transferOwnership(account);
    }
}

File 11 of 57 : OwnableInternal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IERC173 } from '../../interfaces/IERC173.sol';
import { AddressUtils } from '../../utils/AddressUtils.sol';
import { IOwnableInternal } from './IOwnableInternal.sol';
import { OwnableStorage } from './OwnableStorage.sol';

abstract contract OwnableInternal is IOwnableInternal {
    using AddressUtils for address;

    modifier onlyOwner() {
        if (msg.sender != _owner()) revert Ownable__NotOwner();
        _;
    }

    modifier onlyTransitiveOwner() {
        if (msg.sender != _transitiveOwner())
            revert Ownable__NotTransitiveOwner();
        _;
    }

    function _owner() internal view virtual returns (address) {
        return OwnableStorage.layout().owner;
    }

    function _transitiveOwner() internal view virtual returns (address owner) {
        owner = _owner();

        while (owner.isContract()) {
            try IERC173(owner).owner() returns (address transitiveOwner) {
                owner = transitiveOwner;
            } catch {
                break;
            }
        }
    }

    function _transferOwnership(address account) internal virtual {
        _setOwner(account);
    }

    function _setOwner(address account) internal virtual {
        OwnableStorage.Layout storage l = OwnableStorage.layout();
        emit OwnershipTransferred(l.owner, account);
        l.owner = account;
    }
}

File 12 of 57 : OwnableStorage.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

library OwnableStorage {
    struct Layout {
        address owner;
    }

    bytes32 internal constant STORAGE_SLOT =
        keccak256('solidstate.contracts.storage.Ownable');

    function layout() internal pure returns (Layout storage l) {
        bytes32 slot = STORAGE_SLOT;
        assembly {
            l.slot := slot
        }
    }
}

File 13 of 57 : SafeOwnable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { Ownable } from './Ownable.sol';
import { ISafeOwnable } from './ISafeOwnable.sol';
import { OwnableInternal } from './OwnableInternal.sol';
import { SafeOwnableInternal } from './SafeOwnableInternal.sol';

/**
 * @title Ownership access control based on ERC173 with ownership transfer safety check
 */
abstract contract SafeOwnable is ISafeOwnable, Ownable, SafeOwnableInternal {
    /**
     * @inheritdoc ISafeOwnable
     */
    function nomineeOwner() public view virtual returns (address) {
        return _nomineeOwner();
    }

    /**
     * @inheritdoc ISafeOwnable
     */
    function acceptOwnership() public virtual onlyNomineeOwner {
        _acceptOwnership();
    }

    function _transferOwnership(
        address account
    ) internal virtual override(OwnableInternal, SafeOwnableInternal) {
        super._transferOwnership(account);
    }
}

File 14 of 57 : SafeOwnableInternal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { ISafeOwnableInternal } from './ISafeOwnableInternal.sol';
import { OwnableInternal } from './OwnableInternal.sol';
import { SafeOwnableStorage } from './SafeOwnableStorage.sol';

abstract contract SafeOwnableInternal is ISafeOwnableInternal, OwnableInternal {
    modifier onlyNomineeOwner() {
        if (msg.sender != _nomineeOwner())
            revert SafeOwnable__NotNomineeOwner();
        _;
    }

    /**
     * @notice get the nominated owner who has permission to call acceptOwnership
     */
    function _nomineeOwner() internal view virtual returns (address) {
        return SafeOwnableStorage.layout().nomineeOwner;
    }

    /**
     * @notice accept transfer of contract ownership
     */
    function _acceptOwnership() internal virtual {
        _setOwner(msg.sender);
        delete SafeOwnableStorage.layout().nomineeOwner;
    }

    /**
     * @notice grant permission to given address to claim contract ownership
     */
    function _transferOwnership(address account) internal virtual override {
        _setNomineeOwner(account);
    }

    /**
     * @notice set nominee owner
     */
    function _setNomineeOwner(address account) internal virtual {
        SafeOwnableStorage.layout().nomineeOwner = account;
    }
}

File 15 of 57 : SafeOwnableStorage.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

library SafeOwnableStorage {
    struct Layout {
        address nomineeOwner;
    }

    bytes32 internal constant STORAGE_SLOT =
        keccak256('solidstate.contracts.storage.SafeOwnable');

    function layout() internal pure returns (Layout storage l) {
        bytes32 slot = STORAGE_SLOT;
        assembly {
            l.slot := slot
        }
    }
}

File 16 of 57 : EnumerableSet.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

/**
 * @title Set implementation with enumeration functions
 * @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts (MIT license)
 */
library EnumerableSet {
    error EnumerableSet__IndexOutOfBounds();

    struct Set {
        bytes32[] _values;
        // 1-indexed to allow 0 to signify nonexistence
        mapping(bytes32 => uint256) _indexes;
    }

    struct Bytes32Set {
        Set _inner;
    }

    struct AddressSet {
        Set _inner;
    }

    struct UintSet {
        Set _inner;
    }

    function at(
        Bytes32Set storage set,
        uint256 index
    ) internal view returns (bytes32) {
        return _at(set._inner, index);
    }

    function at(
        AddressSet storage set,
        uint256 index
    ) internal view returns (address) {
        return address(uint160(uint256(_at(set._inner, index))));
    }

    function at(
        UintSet storage set,
        uint256 index
    ) internal view returns (uint256) {
        return uint256(_at(set._inner, index));
    }

    function contains(
        Bytes32Set storage set,
        bytes32 value
    ) internal view returns (bool) {
        return _contains(set._inner, value);
    }

    function contains(
        AddressSet storage set,
        address value
    ) internal view returns (bool) {
        return _contains(set._inner, bytes32(uint256(uint160(value))));
    }

    function contains(
        UintSet storage set,
        uint256 value
    ) internal view returns (bool) {
        return _contains(set._inner, bytes32(value));
    }

    function indexOf(
        Bytes32Set storage set,
        bytes32 value
    ) internal view returns (uint256) {
        return _indexOf(set._inner, value);
    }

    function indexOf(
        AddressSet storage set,
        address value
    ) internal view returns (uint256) {
        return _indexOf(set._inner, bytes32(uint256(uint160(value))));
    }

    function indexOf(
        UintSet storage set,
        uint256 value
    ) internal view returns (uint256) {
        return _indexOf(set._inner, bytes32(value));
    }

    function length(Bytes32Set storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    function add(
        Bytes32Set storage set,
        bytes32 value
    ) internal returns (bool) {
        return _add(set._inner, value);
    }

    function add(
        AddressSet storage set,
        address value
    ) internal returns (bool) {
        return _add(set._inner, bytes32(uint256(uint160(value))));
    }

    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    function remove(
        Bytes32Set storage set,
        bytes32 value
    ) internal returns (bool) {
        return _remove(set._inner, value);
    }

    function remove(
        AddressSet storage set,
        address value
    ) internal returns (bool) {
        return _remove(set._inner, bytes32(uint256(uint160(value))));
    }

    function remove(
        UintSet storage set,
        uint256 value
    ) internal returns (bool) {
        return _remove(set._inner, bytes32(value));
    }

    function toArray(
        Bytes32Set storage set
    ) internal view returns (bytes32[] memory) {
        return set._inner._values;
    }

    function toArray(
        AddressSet storage set
    ) internal view returns (address[] memory) {
        bytes32[] storage values = set._inner._values;
        address[] storage array;

        assembly {
            array.slot := values.slot
        }

        return array;
    }

    function toArray(
        UintSet storage set
    ) internal view returns (uint256[] memory) {
        bytes32[] storage values = set._inner._values;
        uint256[] storage array;

        assembly {
            array.slot := values.slot
        }

        return array;
    }

    function _at(
        Set storage set,
        uint256 index
    ) private view returns (bytes32) {
        if (index >= set._values.length)
            revert EnumerableSet__IndexOutOfBounds();
        return set._values[index];
    }

    function _contains(
        Set storage set,
        bytes32 value
    ) private view returns (bool) {
        return set._indexes[value] != 0;
    }

    function _indexOf(
        Set storage set,
        bytes32 value
    ) private view returns (uint256) {
        unchecked {
            return set._indexes[value] - 1;
        }
    }

    function _length(Set storage set) private view returns (uint256) {
        return set._values.length;
    }

    function _add(
        Set storage set,
        bytes32 value
    ) private returns (bool status) {
        if (!_contains(set, value)) {
            set._values.push(value);
            set._indexes[value] = set._values.length;
            status = true;
        }
    }

    function _remove(
        Set storage set,
        bytes32 value
    ) private returns (bool status) {
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) {
            unchecked {
                bytes32 last = set._values[set._values.length - 1];

                // move last value to now-vacant index

                set._values[valueIndex - 1] = last;
                set._indexes[last] = valueIndex;
            }
            // clear last index

            set._values.pop();
            delete set._indexes[value];

            status = true;
        }
    }
}

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

pragma solidity ^0.8.8;

import { IERC165Internal } from './IERC165Internal.sol';

/**
 * @title ERC165 interface registration interface
 * @dev see https://eips.ethereum.org/EIPS/eip-165
 */
interface IERC165 is IERC165Internal {
    /**
     * @notice query whether contract has registered support for given interface
     * @param interfaceId interface id
     * @return bool whether interface is supported
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

File 18 of 57 : IERC165Internal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

/**
 * @title ERC165 interface registration interface
 */
interface IERC165Internal {

}

File 19 of 57 : IERC173.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IERC173Internal } from './IERC173Internal.sol';

/**
 * @title Contract ownership standard interface
 * @dev see https://eips.ethereum.org/EIPS/eip-173
 */
interface IERC173 is IERC173Internal {
    /**
     * @notice get the ERC173 contract owner
     * @return contract owner
     */
    function owner() external view returns (address);

    /**
     * @notice transfer contract ownership to new account
     * @param account address of new owner
     */
    function transferOwnership(address account) external;
}

File 20 of 57 : IERC173Internal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

/**
 * @title Partial ERC173 interface needed by internal functions
 */
interface IERC173Internal {
    event OwnershipTransferred(
        address indexed previousOwner,
        address indexed newOwner
    );
}

File 21 of 57 : IERC2981.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IERC165 } from './IERC165.sol';
import { IERC2981Internal } from './IERC2981Internal.sol';

/**
 * @title ERC2981 interface
 * @dev see https://eips.ethereum.org/EIPS/eip-2981
 */
interface IERC2981 is IERC2981Internal, IERC165 {
    /**
     * @notice called with the sale price to determine how much royalty is owed and to whom
     * @param tokenId the ERC721 or ERC1155 token id to query for royalty information
     * @param salePrice the sale price of the given asset
     * @return receiever rightful recipient of royalty
     * @return royaltyAmount amount of royalty owed
     */
    function royaltyInfo(
        uint256 tokenId,
        uint256 salePrice
    ) external view returns (address receiever, uint256 royaltyAmount);
}

File 22 of 57 : IERC2981Internal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

/**
 * @title ERC2981 interface
 */
interface IERC2981Internal {

}

File 23 of 57 : IERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IERC165 } from './IERC165.sol';
import { IERC721Internal } from './IERC721Internal.sol';

/**
 * @title ERC721 interface
 * @dev see https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721 is IERC721Internal, IERC165 {
    /**
     * @notice query the balance of given address
     * @return balance quantity of tokens held
     */
    function balanceOf(address account) external view returns (uint256 balance);

    /**
     * @notice query the owner of given token
     * @param tokenId token to query
     * @return owner token owner
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @notice transfer token between given addresses, checking for ERC721Receiver implementation if applicable
     * @param from sender of token
     * @param to receiver of token
     * @param tokenId token id
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external payable;

    /**
     * @notice transfer token between given addresses, checking for ERC721Receiver implementation if applicable
     * @param from sender of token
     * @param to receiver of token
     * @param tokenId token id
     * @param data data payload
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external payable;

    /**
     * @notice transfer token between given addresses, without checking for ERC721Receiver implementation if applicable
     * @param from sender of token
     * @param to receiver of token
     * @param tokenId token id
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external payable;

    /**
     * @notice grant approval to given account to spend token
     * @param operator address to be approved
     * @param tokenId token to approve
     */
    function approve(address operator, uint256 tokenId) external payable;

    /**
     * @notice get approval status for given token
     * @param tokenId token to query
     * @return operator address approved to spend token
     */
    function getApproved(
        uint256 tokenId
    ) external view returns (address operator);

    /**
     * @notice grant approval to or revoke approval from given account to spend all tokens held by sender
     * @param operator address to be approved
     * @param status approval status
     */
    function setApprovalForAll(address operator, bool status) external;

    /**
     * @notice query approval status of given operator with respect to given address
     * @param account address to query for approval granted
     * @param operator address to query for approval received
     * @return status whether operator is approved to spend tokens held by account
     */
    function isApprovedForAll(
        address account,
        address operator
    ) external view returns (bool status);
}

File 24 of 57 : IERC721Internal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

/**
 * @title Partial ERC721 interface needed by internal functions
 */
interface IERC721Internal {
    event Transfer(
        address indexed from,
        address indexed to,
        uint256 indexed tokenId
    );

    event Approval(
        address indexed owner,
        address indexed operator,
        uint256 indexed tokenId
    );

    event ApprovalForAll(
        address indexed owner,
        address indexed operator,
        bool approved
    );
}

File 25 of 57 : ERC165Base.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IERC165 } from '../../../interfaces/IERC165.sol';
import { IERC165Base } from './IERC165Base.sol';
import { ERC165BaseInternal } from './ERC165BaseInternal.sol';
import { ERC165BaseStorage } from './ERC165BaseStorage.sol';

/**
 * @title ERC165 implementation
 */
abstract contract ERC165Base is IERC165Base, ERC165BaseInternal {
    /**
     * @inheritdoc IERC165
     */
    function supportsInterface(bytes4 interfaceId) public view returns (bool) {
        return _supportsInterface(interfaceId);
    }
}

File 26 of 57 : ERC165BaseInternal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IERC165BaseInternal } from './IERC165BaseInternal.sol';
import { ERC165BaseStorage } from './ERC165BaseStorage.sol';

/**
 * @title ERC165 implementation
 */
abstract contract ERC165BaseInternal is IERC165BaseInternal {
    /**
     * @notice indicates whether an interface is already supported based on the interfaceId
     * @param interfaceId id of interface to check
     * @return bool indicating whether interface is supported
     */
    function _supportsInterface(
        bytes4 interfaceId
    ) internal view virtual returns (bool) {
        return ERC165BaseStorage.layout().supportedInterfaces[interfaceId];
    }

    /**
     * @notice sets status of interface support
     * @param interfaceId id of interface to set status for
     * @param status boolean indicating whether interface will be set as supported
     */
    function _setSupportsInterface(
        bytes4 interfaceId,
        bool status
    ) internal virtual {
        if (interfaceId == 0xffffffff) revert ERC165Base__InvalidInterfaceId();
        ERC165BaseStorage.layout().supportedInterfaces[interfaceId] = status;
    }
}

File 27 of 57 : ERC165BaseStorage.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

library ERC165BaseStorage {
    struct Layout {
        mapping(bytes4 => bool) supportedInterfaces;
    }

    bytes32 internal constant STORAGE_SLOT =
        keccak256('solidstate.contracts.storage.ERC165Base');

    function layout() internal pure returns (Layout storage l) {
        bytes32 slot = STORAGE_SLOT;
        assembly {
            l.slot := slot
        }
    }
}

File 28 of 57 : IERC165Base.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IERC165 } from '../../../interfaces/IERC165.sol';
import { IERC165BaseInternal } from './IERC165BaseInternal.sol';

interface IERC165Base is IERC165, IERC165BaseInternal {}

File 29 of 57 : IERC165BaseInternal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IERC165Internal } from '../../../interfaces/IERC165Internal.sol';

interface IERC165BaseInternal is IERC165Internal {
    error ERC165Base__InvalidInterfaceId();
}

File 30 of 57 : DiamondBase.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { Proxy } from '../../Proxy.sol';
import { IDiamondBase } from './IDiamondBase.sol';
import { DiamondBaseStorage } from './DiamondBaseStorage.sol';

/**
 * @title EIP-2535 "Diamond" proxy base contract
 * @dev see https://eips.ethereum.org/EIPS/eip-2535
 */
abstract contract DiamondBase is IDiamondBase, Proxy {
    /**
     * @inheritdoc Proxy
     */
    function _getImplementation()
        internal
        view
        virtual
        override
        returns (address implementation)
    {
        // inline storage layout retrieval uses less gas
        DiamondBaseStorage.Layout storage l;
        bytes32 slot = DiamondBaseStorage.STORAGE_SLOT;
        assembly {
            l.slot := slot
        }

        implementation = address(bytes20(l.facets[msg.sig]));
    }
}

File 31 of 57 : DiamondBaseStorage.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

/**
 * @dev derived from https://github.com/mudgen/diamond-2 (MIT license)
 */
library DiamondBaseStorage {
    struct Layout {
        // function selector => (facet address, selector slot position)
        mapping(bytes4 => bytes32) facets;
        // total number of selectors registered
        uint16 selectorCount;
        // array of selector slots with 8 selectors per slot
        mapping(uint256 => bytes32) selectorSlots;
        address fallbackAddress;
    }

    bytes32 internal constant STORAGE_SLOT =
        keccak256('solidstate.contracts.storage.DiamondBase');

    function layout() internal pure returns (Layout storage l) {
        bytes32 slot = STORAGE_SLOT;
        assembly {
            l.slot := slot
        }
    }
}

File 32 of 57 : IDiamondBase.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IProxy } from '../../IProxy.sol';

interface IDiamondBase is IProxy {}

File 33 of 57 : DiamondFallback.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { OwnableInternal } from '../../../access/ownable/OwnableInternal.sol';
import { DiamondBase } from '../base/DiamondBase.sol';
import { DiamondBaseStorage } from '../base/DiamondBaseStorage.sol';
import { IDiamondFallback } from './IDiamondFallback.sol';

/**
 * @title Fallback feature for EIP-2535 "Diamond" proxy
 */
abstract contract DiamondFallback is
    IDiamondFallback,
    OwnableInternal,
    DiamondBase
{
    /**
     * @inheritdoc IDiamondFallback
     */
    function getFallbackAddress()
        external
        view
        returns (address fallbackAddress)
    {
        fallbackAddress = _getFallbackAddress();
    }

    /**
     * @inheritdoc IDiamondFallback
     */
    function setFallbackAddress(address fallbackAddress) external onlyOwner {
        _setFallbackAddress(fallbackAddress);
    }

    /**
     * @inheritdoc DiamondBase
     * @notice query custom fallback address is no implementation is found
     */
    function _getImplementation()
        internal
        view
        virtual
        override
        returns (address implementation)
    {
        implementation = super._getImplementation();

        if (implementation == address(0)) {
            implementation = _getFallbackAddress();
        }
    }

    /**
     * @notice query the address of the fallback implementation
     * @return fallbackAddress address of fallback implementation
     */
    function _getFallbackAddress()
        internal
        view
        virtual
        returns (address fallbackAddress)
    {
        fallbackAddress = DiamondBaseStorage.layout().fallbackAddress;
    }

    /**
     * @notice set the address of the fallback implementation
     * @param fallbackAddress address of fallback implementation
     */
    function _setFallbackAddress(address fallbackAddress) internal virtual {
        DiamondBaseStorage.layout().fallbackAddress = fallbackAddress;
    }
}

File 34 of 57 : IDiamondFallback.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IDiamondBase } from '../base/IDiamondBase.sol';

interface IDiamondFallback is IDiamondBase {
    /**
     * @notice query the address of the fallback implementation
     * @return fallbackAddress address of fallback implementation
     */
    function getFallbackAddress()
        external
        view
        returns (address fallbackAddress);

    /**
     * @notice set the address of the fallback implementation
     * @param fallbackAddress address of fallback implementation
     */
    function setFallbackAddress(address fallbackAddress) external;
}

File 35 of 57 : ISolidStateDiamond.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { ISafeOwnable } from '../../access/ownable/ISafeOwnable.sol';
import { IERC165 } from '../../interfaces/IERC165.sol';
import { IDiamondBase } from './base/IDiamondBase.sol';
import { IDiamondFallback } from './fallback/IDiamondFallback.sol';
import { IDiamondReadable } from './readable/IDiamondReadable.sol';
import { IDiamondWritable } from './writable/IDiamondWritable.sol';

interface ISolidStateDiamond is
    IDiamondBase,
    IDiamondFallback,
    IDiamondReadable,
    IDiamondWritable,
    ISafeOwnable,
    IERC165
{
    receive() external payable;
}

File 36 of 57 : DiamondReadable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { DiamondBaseStorage } from '../base/DiamondBaseStorage.sol';
import { IDiamondReadable } from './IDiamondReadable.sol';

/**
 * @title EIP-2535 "Diamond" proxy introspection contract
 * @dev derived from https://github.com/mudgen/diamond-2 (MIT license)
 */
abstract contract DiamondReadable is IDiamondReadable {
    /**
     * @inheritdoc IDiamondReadable
     */
    function facets() external view returns (Facet[] memory diamondFacets) {
        DiamondBaseStorage.Layout storage l = DiamondBaseStorage.layout();

        diamondFacets = new Facet[](l.selectorCount);

        uint8[] memory numFacetSelectors = new uint8[](l.selectorCount);
        uint256 numFacets;
        uint256 selectorIndex;

        // loop through function selectors
        for (uint256 slotIndex; selectorIndex < l.selectorCount; slotIndex++) {
            bytes32 slot = l.selectorSlots[slotIndex];

            for (
                uint256 selectorSlotIndex;
                selectorSlotIndex < 8;
                selectorSlotIndex++
            ) {
                selectorIndex++;

                if (selectorIndex > l.selectorCount) {
                    break;
                }

                bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));
                address facet = address(bytes20(l.facets[selector]));

                bool continueLoop;

                for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {
                    if (diamondFacets[facetIndex].target == facet) {
                        diamondFacets[facetIndex].selectors[
                            numFacetSelectors[facetIndex]
                        ] = selector;
                        // probably will never have more than 256 functions from one facet contract
                        require(numFacetSelectors[facetIndex] < 255);
                        numFacetSelectors[facetIndex]++;
                        continueLoop = true;
                        break;
                    }
                }

                if (continueLoop) {
                    continue;
                }

                diamondFacets[numFacets].target = facet;
                diamondFacets[numFacets].selectors = new bytes4[](
                    l.selectorCount
                );
                diamondFacets[numFacets].selectors[0] = selector;
                numFacetSelectors[numFacets] = 1;
                numFacets++;
            }
        }

        for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {
            uint256 numSelectors = numFacetSelectors[facetIndex];
            bytes4[] memory selectors = diamondFacets[facetIndex].selectors;

            // setting the number of selectors
            assembly {
                mstore(selectors, numSelectors)
            }
        }

        // setting the number of facets
        assembly {
            mstore(diamondFacets, numFacets)
        }
    }

    /**
     * @inheritdoc IDiamondReadable
     */
    function facetFunctionSelectors(
        address facet
    ) external view returns (bytes4[] memory selectors) {
        DiamondBaseStorage.Layout storage l = DiamondBaseStorage.layout();

        selectors = new bytes4[](l.selectorCount);

        uint256 numSelectors;
        uint256 selectorIndex;

        // loop through function selectors
        for (uint256 slotIndex; selectorIndex < l.selectorCount; slotIndex++) {
            bytes32 slot = l.selectorSlots[slotIndex];

            for (
                uint256 selectorSlotIndex;
                selectorSlotIndex < 8;
                selectorSlotIndex++
            ) {
                selectorIndex++;

                if (selectorIndex > l.selectorCount) {
                    break;
                }

                bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));

                if (facet == address(bytes20(l.facets[selector]))) {
                    selectors[numSelectors] = selector;
                    numSelectors++;
                }
            }
        }

        // set the number of selectors in the array
        assembly {
            mstore(selectors, numSelectors)
        }
    }

    /**
     * @inheritdoc IDiamondReadable
     */
    function facetAddresses()
        external
        view
        returns (address[] memory addresses)
    {
        DiamondBaseStorage.Layout storage l = DiamondBaseStorage.layout();

        addresses = new address[](l.selectorCount);
        uint256 numFacets;
        uint256 selectorIndex;

        for (uint256 slotIndex; selectorIndex < l.selectorCount; slotIndex++) {
            bytes32 slot = l.selectorSlots[slotIndex];

            for (
                uint256 selectorSlotIndex;
                selectorSlotIndex < 8;
                selectorSlotIndex++
            ) {
                selectorIndex++;

                if (selectorIndex > l.selectorCount) {
                    break;
                }

                bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));
                address facet = address(bytes20(l.facets[selector]));

                bool continueLoop;

                for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {
                    if (facet == addresses[facetIndex]) {
                        continueLoop = true;
                        break;
                    }
                }

                if (continueLoop) {
                    continue;
                }

                addresses[numFacets] = facet;
                numFacets++;
            }
        }

        // set the number of facet addresses in the array
        assembly {
            mstore(addresses, numFacets)
        }
    }

    /**
     * @inheritdoc IDiamondReadable
     */
    function facetAddress(
        bytes4 selector
    ) external view returns (address facet) {
        facet = address(bytes20(DiamondBaseStorage.layout().facets[selector]));
    }
}

File 37 of 57 : IDiamondReadable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

/**
 * @title Diamond proxy introspection interface
 * @dev see https://eips.ethereum.org/EIPS/eip-2535
 */
interface IDiamondReadable {
    struct Facet {
        address target;
        bytes4[] selectors;
    }

    /**
     * @notice get all facets and their selectors
     * @return diamondFacets array of structured facet data
     */
    function facets() external view returns (Facet[] memory diamondFacets);

    /**
     * @notice get all selectors for given facet address
     * @param facet address of facet to query
     * @return selectors array of function selectors
     */
    function facetFunctionSelectors(
        address facet
    ) external view returns (bytes4[] memory selectors);

    /**
     * @notice get addresses of all facets used by diamond
     * @return addresses array of facet addresses
     */
    function facetAddresses()
        external
        view
        returns (address[] memory addresses);

    /**
     * @notice get the address of the facet associated with given selector
     * @param selector function selector to query
     * @return facet facet address (zero address if not found)
     */
    function facetAddress(
        bytes4 selector
    ) external view returns (address facet);
}

File 38 of 57 : DiamondWritable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { OwnableInternal } from '../../../access/ownable/OwnableInternal.sol';
import { IDiamondWritable } from './IDiamondWritable.sol';
import { DiamondWritableInternal } from './DiamondWritableInternal.sol';

/**
 * @title EIP-2535 "Diamond" proxy update contract
 */
abstract contract DiamondWritable is
    IDiamondWritable,
    DiamondWritableInternal,
    OwnableInternal
{
    /**
     * @inheritdoc IDiamondWritable
     */
    function diamondCut(
        FacetCut[] calldata facetCuts,
        address target,
        bytes calldata data
    ) external onlyOwner {
        _diamondCut(facetCuts, target, data);
    }
}

File 39 of 57 : DiamondWritableInternal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { AddressUtils } from '../../../utils/AddressUtils.sol';
import { DiamondBaseStorage } from '../base/DiamondBaseStorage.sol';
import { IDiamondWritableInternal } from './IDiamondWritableInternal.sol';

abstract contract DiamondWritableInternal is IDiamondWritableInternal {
    using AddressUtils for address;

    bytes32 private constant CLEAR_ADDRESS_MASK =
        bytes32(uint256(0xffffffffffffffffffffffff));
    bytes32 private constant CLEAR_SELECTOR_MASK =
        bytes32(uint256(0xffffffff << 224));

    /**
     * @notice update functions callable on Diamond proxy
     * @param facetCuts array of structured Diamond facet update data
     * @param target optional recipient of initialization delegatecall
     * @param data optional initialization call data
     */
    function _diamondCut(
        FacetCut[] memory facetCuts,
        address target,
        bytes memory data
    ) internal {
        DiamondBaseStorage.Layout storage l = DiamondBaseStorage.layout();

        unchecked {
            uint256 originalSelectorCount = l.selectorCount;
            uint256 selectorCount = originalSelectorCount;
            bytes32 selectorSlot;

            // Check if last selector slot is not full
            if (selectorCount & 7 > 0) {
                // get last selectorSlot
                selectorSlot = l.selectorSlots[selectorCount >> 3];
            }

            for (uint256 i; i < facetCuts.length; i++) {
                FacetCut memory facetCut = facetCuts[i];
                FacetCutAction action = facetCut.action;

                if (facetCut.selectors.length == 0)
                    revert DiamondWritable__SelectorNotSpecified();

                if (action == FacetCutAction.ADD) {
                    (selectorCount, selectorSlot) = _addFacetSelectors(
                        l,
                        selectorCount,
                        selectorSlot,
                        facetCut
                    );
                } else if (action == FacetCutAction.REPLACE) {
                    _replaceFacetSelectors(l, facetCut);
                } else if (action == FacetCutAction.REMOVE) {
                    (selectorCount, selectorSlot) = _removeFacetSelectors(
                        l,
                        selectorCount,
                        selectorSlot,
                        facetCut
                    );
                }
            }

            if (selectorCount != originalSelectorCount) {
                l.selectorCount = uint16(selectorCount);
            }

            // If last selector slot is not full
            if (selectorCount & 7 > 0) {
                l.selectorSlots[selectorCount >> 3] = selectorSlot;
            }

            emit DiamondCut(facetCuts, target, data);
            _initialize(target, data);
        }
    }

    function _addFacetSelectors(
        DiamondBaseStorage.Layout storage l,
        uint256 selectorCount,
        bytes32 selectorSlot,
        FacetCut memory facetCut
    ) internal returns (uint256, bytes32) {
        unchecked {
            if (
                facetCut.target != address(this) &&
                !facetCut.target.isContract()
            ) revert DiamondWritable__TargetHasNoCode();

            for (uint256 i; i < facetCut.selectors.length; i++) {
                bytes4 selector = facetCut.selectors[i];
                bytes32 oldFacet = l.facets[selector];

                if (address(bytes20(oldFacet)) != address(0))
                    revert DiamondWritable__SelectorAlreadyAdded();

                // add facet for selector
                l.facets[selector] =
                    bytes20(facetCut.target) |
                    bytes32(selectorCount);
                uint256 selectorInSlotPosition = (selectorCount & 7) << 5;

                // clear selector position in slot and add selector
                selectorSlot =
                    (selectorSlot &
                        ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |
                    (bytes32(selector) >> selectorInSlotPosition);

                // if slot is full then write it to storage
                if (selectorInSlotPosition == 224) {
                    l.selectorSlots[selectorCount >> 3] = selectorSlot;
                    selectorSlot = 0;
                }

                selectorCount++;
            }

            return (selectorCount, selectorSlot);
        }
    }

    function _removeFacetSelectors(
        DiamondBaseStorage.Layout storage l,
        uint256 selectorCount,
        bytes32 selectorSlot,
        FacetCut memory facetCut
    ) internal returns (uint256, bytes32) {
        unchecked {
            if (facetCut.target != address(0))
                revert DiamondWritable__RemoveTargetNotZeroAddress();

            uint256 selectorSlotCount = selectorCount >> 3;
            uint256 selectorInSlotIndex = selectorCount & 7;

            for (uint256 i; i < facetCut.selectors.length; i++) {
                bytes4 selector = facetCut.selectors[i];
                bytes32 oldFacet = l.facets[selector];

                if (address(bytes20(oldFacet)) == address(0))
                    revert DiamondWritable__SelectorNotFound();

                if (address(bytes20(oldFacet)) == address(this))
                    revert DiamondWritable__SelectorIsImmutable();

                if (selectorSlot == 0) {
                    selectorSlotCount--;
                    selectorSlot = l.selectorSlots[selectorSlotCount];
                    selectorInSlotIndex = 7;
                } else {
                    selectorInSlotIndex--;
                }

                bytes4 lastSelector;
                uint256 oldSelectorsSlotCount;
                uint256 oldSelectorInSlotPosition;

                // adding a block here prevents stack too deep error
                {
                    // replace selector with last selector in l.facets
                    lastSelector = bytes4(
                        selectorSlot << (selectorInSlotIndex << 5)
                    );

                    if (lastSelector != selector) {
                        // update last selector slot position info
                        l.facets[lastSelector] =
                            (oldFacet & CLEAR_ADDRESS_MASK) |
                            bytes20(l.facets[lastSelector]);
                    }

                    delete l.facets[selector];
                    uint256 oldSelectorCount = uint16(uint256(oldFacet));
                    oldSelectorsSlotCount = oldSelectorCount >> 3;
                    oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;
                }

                if (oldSelectorsSlotCount != selectorSlotCount) {
                    bytes32 oldSelectorSlot = l.selectorSlots[
                        oldSelectorsSlotCount
                    ];

                    // clears the selector we are deleting and puts the last selector in its place.
                    oldSelectorSlot =
                        (oldSelectorSlot &
                            ~(CLEAR_SELECTOR_MASK >>
                                oldSelectorInSlotPosition)) |
                        (bytes32(lastSelector) >> oldSelectorInSlotPosition);

                    // update storage with the modified slot
                    l.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;
                } else {
                    // clears the selector we are deleting and puts the last selector in its place.
                    selectorSlot =
                        (selectorSlot &
                            ~(CLEAR_SELECTOR_MASK >>
                                oldSelectorInSlotPosition)) |
                        (bytes32(lastSelector) >> oldSelectorInSlotPosition);
                }

                if (selectorInSlotIndex == 0) {
                    delete l.selectorSlots[selectorSlotCount];
                    selectorSlot = 0;
                }
            }

            selectorCount = (selectorSlotCount << 3) | selectorInSlotIndex;

            return (selectorCount, selectorSlot);
        }
    }

    function _replaceFacetSelectors(
        DiamondBaseStorage.Layout storage l,
        FacetCut memory facetCut
    ) internal {
        unchecked {
            if (!facetCut.target.isContract())
                revert DiamondWritable__TargetHasNoCode();

            for (uint256 i; i < facetCut.selectors.length; i++) {
                bytes4 selector = facetCut.selectors[i];
                bytes32 oldFacet = l.facets[selector];
                address oldFacetAddress = address(bytes20(oldFacet));

                if (oldFacetAddress == address(0))
                    revert DiamondWritable__SelectorNotFound();
                if (oldFacetAddress == address(this))
                    revert DiamondWritable__SelectorIsImmutable();
                if (oldFacetAddress == facetCut.target)
                    revert DiamondWritable__ReplaceTargetIsIdentical();

                // replace old facet address
                l.facets[selector] =
                    (oldFacet & CLEAR_ADDRESS_MASK) |
                    bytes20(facetCut.target);
            }
        }
    }

    function _initialize(address target, bytes memory data) private {
        if ((target == address(0)) != (data.length == 0))
            revert DiamondWritable__InvalidInitializationParameters();

        if (target != address(0)) {
            if (target != address(this)) {
                if (!target.isContract())
                    revert DiamondWritable__TargetHasNoCode();
            }

            (bool success, ) = target.delegatecall(data);

            if (!success) {
                assembly {
                    returndatacopy(0, 0, returndatasize())
                    revert(0, returndatasize())
                }
            }
        }
    }
}

File 40 of 57 : IDiamondWritable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IDiamondWritableInternal } from './IDiamondWritableInternal.sol';

/**
 * @title Diamond proxy upgrade interface
 * @dev see https://eips.ethereum.org/EIPS/eip-2535
 */
interface IDiamondWritable is IDiamondWritableInternal {
    /**
     * @notice update diamond facets and optionally execute arbitrary initialization function
     * @param facetCuts array of structured Diamond facet update data
     * @param target optional target of initialization delegatecall
     * @param data optional initialization function call data
     */
    function diamondCut(
        FacetCut[] calldata facetCuts,
        address target,
        bytes calldata data
    ) external;
}

File 41 of 57 : IDiamondWritableInternal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

interface IDiamondWritableInternal {
    enum FacetCutAction {
        ADD,
        REPLACE,
        REMOVE
    }

    event DiamondCut(FacetCut[] facetCuts, address target, bytes data);

    error DiamondWritable__InvalidInitializationParameters();
    error DiamondWritable__RemoveTargetNotZeroAddress();
    error DiamondWritable__ReplaceTargetIsIdentical();
    error DiamondWritable__SelectorAlreadyAdded();
    error DiamondWritable__SelectorIsImmutable();
    error DiamondWritable__SelectorNotFound();
    error DiamondWritable__SelectorNotSpecified();
    error DiamondWritable__TargetHasNoCode();

    struct FacetCut {
        address target;
        FacetCutAction action;
        bytes4[] selectors;
    }
}

File 42 of 57 : IProxy.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

interface IProxy {
    error Proxy__ImplementationIsNotContract();

    fallback() external payable;
}

File 43 of 57 : Proxy.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { AddressUtils } from '../utils/AddressUtils.sol';
import { IProxy } from './IProxy.sol';

/**
 * @title Base proxy contract
 */
abstract contract Proxy is IProxy {
    using AddressUtils for address;

    /**
     * @notice delegate all calls to implementation contract
     * @dev reverts if implementation address contains no code, for compatibility with metamorphic contracts
     * @dev memory location in use by assembly may be unsafe in other contexts
     */
    fallback() external payable virtual {
        address implementation = _getImplementation();

        if (!implementation.isContract())
            revert Proxy__ImplementationIsNotContract();

        assembly {
            calldatacopy(0, 0, calldatasize())
            let result := delegatecall(
                gas(),
                implementation,
                0,
                calldatasize(),
                0,
                0
            )
            returndatacopy(0, 0, returndatasize())

            switch result
            case 0 {
                revert(0, returndatasize())
            }
            default {
                return(0, returndatasize())
            }
        }
    }

    /**
     * @notice get logic implementation address
     * @return implementation address
     */
    function _getImplementation() internal virtual returns (address);
}

File 44 of 57 : ERC2981Storage.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

library ERC2981Storage {
    struct Layout {
        // token id -> royalty (denominated in basis points)
        mapping(uint256 => uint16) royaltiesBPS;
        uint16 defaultRoyaltyBPS;
        // token id -> receiver address
        mapping(uint256 => address) royaltyReceivers;
        address defaultRoyaltyReceiver;
    }

    bytes32 internal constant STORAGE_SLOT =
        keccak256('solidstate.contracts.storage.ERC2981');

    function layout() internal pure returns (Layout storage l) {
        bytes32 slot = STORAGE_SLOT;
        assembly {
            l.slot := slot
        }
    }
}

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

pragma solidity ^0.8.8;

interface IERC721Enumerable {
    /**
     * @notice get total token supply
     * @return total supply
     */
    function totalSupply() external view returns (uint256);

    /**
     * @notice get token of given owner at given internal storage index
     * @param owner token holder to query
     * @param index position in owner's token list to query
     * @return tokenId id of retrieved token
     */
    function tokenOfOwnerByIndex(
        address owner,
        uint256 index
    ) external view returns (uint256 tokenId);

    /**
     * @notice get token at given internal storage index
     * @param index position in global token list to query
     * @return tokenId id of retrieved token
     */
    function tokenByIndex(
        uint256 index
    ) external view returns (uint256 tokenId);
}

File 46 of 57 : ERC721MetadataStorage.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

library ERC721MetadataStorage {
    bytes32 internal constant STORAGE_SLOT =
        keccak256('solidstate.contracts.storage.ERC721Metadata');

    struct Layout {
        string name;
        string symbol;
        string baseURI;
        mapping(uint256 => string) tokenURIs;
    }

    function layout() internal pure returns (Layout storage l) {
        bytes32 slot = STORAGE_SLOT;
        assembly {
            l.slot := slot
        }
    }
}

File 47 of 57 : AddressUtils.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { UintUtils } from './UintUtils.sol';

library AddressUtils {
    using UintUtils for uint256;

    error AddressUtils__InsufficientBalance();
    error AddressUtils__NotContract();
    error AddressUtils__SendValueFailed();

    function toString(address account) internal pure returns (string memory) {
        return uint256(uint160(account)).toHexString(20);
    }

    function isContract(address account) internal view returns (bool) {
        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

    function sendValue(address payable account, uint256 amount) internal {
        (bool success, ) = account.call{ value: amount }('');
        if (!success) revert AddressUtils__SendValueFailed();
    }

    function functionCall(
        address target,
        bytes memory data
    ) internal returns (bytes memory) {
        return
            functionCall(target, data, 'AddressUtils: failed low-level call');
    }

    function functionCall(
        address target,
        bytes memory data,
        string memory error
    ) internal returns (bytes memory) {
        return _functionCallWithValue(target, data, 0, error);
    }

    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return
            functionCallWithValue(
                target,
                data,
                value,
                'AddressUtils: failed low-level call with value'
            );
    }

    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory error
    ) internal returns (bytes memory) {
        if (value > address(this).balance)
            revert AddressUtils__InsufficientBalance();
        return _functionCallWithValue(target, data, value, error);
    }

    /**
     * @notice execute arbitrary external call with limited gas usage and amount of copied return data
     * @dev derived from https://github.com/nomad-xyz/ExcessivelySafeCall (MIT License)
     * @param target recipient of call
     * @param gasAmount gas allowance for call
     * @param value native token value to include in call
     * @param maxCopy maximum number of bytes to copy from return data
     * @param data encoded call data
     * @return success whether call is successful
     * @return returnData copied return data
     */
    function excessivelySafeCall(
        address target,
        uint256 gasAmount,
        uint256 value,
        uint16 maxCopy,
        bytes memory data
    ) internal returns (bool success, bytes memory returnData) {
        returnData = new bytes(maxCopy);

        assembly {
            // execute external call via assembly to avoid automatic copying of return data
            success := call(
                gasAmount,
                target,
                value,
                add(data, 0x20),
                mload(data),
                0,
                0
            )

            // determine whether to limit amount of data to copy
            let toCopy := returndatasize()

            if gt(toCopy, maxCopy) {
                toCopy := maxCopy
            }

            // store the length of the copied bytes
            mstore(returnData, toCopy)

            // copy the bytes from returndata[0:toCopy]
            returndatacopy(add(returnData, 0x20), 0, toCopy)
        }
    }

    function _functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory error
    ) private returns (bytes memory) {
        if (!isContract(target)) revert AddressUtils__NotContract();

        (bool success, bytes memory returnData) = target.call{ value: value }(
            data
        );

        if (success) {
            return returnData;
        } else if (returnData.length > 0) {
            assembly {
                let returnData_size := mload(returnData)
                revert(add(32, returnData), returnData_size)
            }
        } else {
            revert(error);
        }
    }
}

File 48 of 57 : UintUtils.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

/**
 * @title utility functions for uint256 operations
 * @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts/ (MIT license)
 */
library UintUtils {
    error UintUtils__InsufficientHexLength();

    bytes16 private constant HEX_SYMBOLS = '0123456789abcdef';

    function add(uint256 a, int256 b) internal pure returns (uint256) {
        return b < 0 ? sub(a, -b) : a + uint256(b);
    }

    function sub(uint256 a, int256 b) internal pure returns (uint256) {
        return b < 0 ? add(a, -b) : a - uint256(b);
    }

    function toString(uint256 value) internal pure returns (string memory) {
        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);
    }

    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return '0x00';
        }

        uint256 length = 0;

        for (uint256 temp = value; temp != 0; temp >>= 8) {
            unchecked {
                length++;
            }
        }

        return toHexString(value, 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';

        unchecked {
            for (uint256 i = 2 * length + 1; i > 1; --i) {
                buffer[i] = HEX_SYMBOLS[value & 0xf];
                value >>= 4;
            }
        }

        if (value != 0) revert UintUtils__InsufficientHexLength();

        return string(buffer);
    }
}

File 49 of 57 : DiamondOperatorFilter.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.18;

import { IOperatorFilterRegistry } from "operator-filter-registry/src/IOperatorFilterRegistry.sol";

/**
 * @dev copied from operator-filter-registry/src/upgradeable/OperatorFiltererUpgradeable.sol
 * @dev some of the control flow was removed to remove unnecessary branches
 */
contract DiamondOperatorFilter {
    IOperatorFilterRegistry constant OPERATOR_FILTER_REGISTRY =
        IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E);

    /// @dev The upgradeable initialize function that should be called when the contract is being upgraded.
    function __OperatorFilterer_init(address subscriptionOrRegistrantToCopy) internal {
        if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) {
            if (!OPERATOR_FILTER_REGISTRY.isRegistered(address(this))) {
                OPERATOR_FILTER_REGISTRY.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);
            }
        }
    }
}

File 50 of 57 : DiamondWritableRevokable.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.18;

import { OwnableInternal } from "@solidstate/contracts/access/ownable/OwnableInternal.sol";
import { IDiamondWritable } from "@solidstate/contracts/proxy/diamond/writable/IDiamondWritable.sol";
import { DiamondWritableInternal } from "@solidstate/contracts/proxy/diamond/writable/DiamondWritableInternal.sol";
import { DiamondWritableRevokableStorage } from "./DiamondWritableRevokableStorage.sol";

/**
 * @title EIP-2535 "Diamond" proxy update contract with built in revokability
 */
abstract contract DiamondWritableRevokable is IDiamondWritable, DiamondWritableInternal, OwnableInternal {
    error UpgradeabilityRevoked();

    /**
     * @inheritdoc IDiamondWritable
     * @dev also checks to ensure upgradeability has not been revoked
     */
    function diamondCut(FacetCut[] calldata facetCuts, address target, bytes calldata data) external onlyOwner {
        if (DiamondWritableRevokableStorage.layout().isUpgradeabiltyRevoked) revert UpgradeabilityRevoked();
        _diamondCut(facetCuts, target, data);
    }
}

File 51 of 57 : DiamondWritableRevokableStorage.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.18;

library DiamondWritableRevokableStorage {
    bytes32 internal constant STORAGE_SLOT = keccak256("keepers.contracts.storage.diamond.writable.revokable");

    struct Layout {
        bool isUpgradeabiltyRevoked;
    }

    function layout() internal pure returns (Layout storage l) {
        bytes32 slot = STORAGE_SLOT;
        assembly {
            l.slot := slot
        }
    }
}

File 52 of 57 : KeepersERC721Storage.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.18;

library KeepersERC721Storage {
    bytes32 internal constant STORAGE_SLOT = keccak256("keepers.contracts.storage.keepers.erc721.storage");

    // @dev struct which describes a commit
    // @dev use uint128 for tight variable packing
    struct MintCommit {
        uint128 numNFTs;
        uint128 commitBlock;
    }

    struct Layout {
        // @dev keeps track of available tokens for fisher yates shuffle
        mapping(uint256 => uint256) availableTokens;
        // @dev a mapping of user address to their pending commit
        mapping(address => MintCommit) pendingCommits;
        // Mint parameters
        mapping(address => uint256) mintCountPerAddress;
        // the following variables will be tightly packed
        uint16 numAvailableTokens;
        uint16 maxPerAddress;
        uint32 saleStartTimestamp; // max val in 2106
        uint32 saleCompleteTimestamp;
        uint160 numPendingCommitNFTs;
        address withdrawAddress;
        address vaultAddress;
        uint256 maxMintsForSalesTier; // when kept at 0 it is ignored
    }

    function layout() internal pure returns (Layout storage l) {
        bytes32 slot = STORAGE_SLOT;
        assembly {
            l.slot := slot
        }
    }
}

File 53 of 57 : TermsStorage.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.18;

import "@openzeppelin/contracts/utils/Counters.sol";

library TermsStorage {
    using Counters for Counters.Counter;

    bytes32 internal constant STORAGE_SLOT = keccak256("keepers.contracts.storage.terms");

    struct Layout {
        mapping(uint256 => string) termsParts; // mapping of term part number to term part string
        Counters.Counter termsVersion;
    }

    function layout() internal pure returns (Layout storage l) {
        bytes32 slot = STORAGE_SLOT;
        assembly {
            l.slot := slot
        }
    }
}

File 54 of 57 : ConstantsLib.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.18;

library ConstantsLib {
    // mint params
    uint256 internal constant MINT_PRICE = 0.5 ether;
    uint256 internal constant ALLOWLSIT_MINT_PRICE = 0.25 ether;

    uint256 internal constant MAX_TICKETS = 20000;
    uint256 internal constant MIN_COMMITMENT_BLOCKS = 4;
    uint256 internal constant MAX_COMMITMENT_BLOCKS = 100;
    uint256 internal constant SPECIAL_TICKETS_COUNT = 10;
    uint256 internal constant SPECIAL_TICKET_MINT_ODDS = 1000;

    // access control
    bytes32 internal constant KEEPERS_TERMS_OPERATOR = keccak256("KEEPERS_TERMS_OPERATOR");
    bytes32 internal constant KEEPERS_LICENSE_OPERATOR = keccak256("KEEPERS_LICENSE_OPERATOR");
    bytes32 internal constant KEEPERS_MINT_OPERATOR = keccak256("KEEPERS_MINT_OPERATOR");

    // token states
    uint256 internal constant TOKEN_STATE_UNCONVERTED = 0;
    uint256 internal constant TOKEN_STATE_USER_CONVERTED = 1;
    uint256 internal constant TOKEN_STATE_ADMIN_CONVERTED = 2;

    // room naming
    uint256 internal constant NO_ROOM_NAMING_RIGHTS = 0;
    uint256 internal constant MAX_ROOM_NAME_LENGTH = 40;
    uint256 internal constant MIN_ROOM_ID = 1;

    // traits
    uint256 internal constant MIN_TRAIT_ID = 1;
    uint256 internal constant MAX_TRAIT_ID = 242;

    uint256 internal constant BLACK_BODY_ID = 1;
    uint256 internal constant GLASS_BODY_ID = 10;
    uint256 internal constant MAX_NON_SPECIAL_BODY_ID = 9;

    // rarities
    // bitmap for ultra rare traits 0000001111100000000000111001101110000000000000000100010000001111100000000000000000000000000000000000000000011100000000000000000000100000000000000000000011101010001000000000000000010000000000000000000000000000000000000000000000000000000000001110000000000000
    uint256 internal constant RARITY_ULTRARARE =
        1752737185771013737644568005558321144114900560241663114319964015025618739200;
    // bitmap for rare traits 0011100000000000000111000000000000000000000000000001100111110000000000000000000000000000000000001000000111100000000000000000010010000001000000000000111100010101110000000000001000100100000000000000000000000000000000000101000001000000111111110000000000000000
    uint256 internal constant RARITY_RARE =
        25329712769560669564647724112116350647150594218874243813999282872231118438400;
    // bitmap for uncommon traits 0000010000000100010000000110010000000000000000001010000000000000000000000000000000000000000001010001111000000000000000000000000001010100001111111111000000000000000100001000110111001000000000000000000000000000000000001010111100110111000000000000000000000000
    uint256 internal constant RARITY_UNCOMMON =
        1816763190353297512045086567763279289688669177570068147176572168506815021056;
    // bitmap for common traits 0100000000011011101000000000000001111111111111110000001000000000011111111111111111111111111110100110000000000011111111111111101100001010110000000000000000000000000011110111000000000011111111111111111111111111111111110000000010001000000000000000000000000000
    uint256 internal constant RARITY_COMMON =
        28996831472973116897448113818906002845680828376134306944232972948193012613120;

    // misc
    uint256 internal constant EMPTY_BITMAP = 0;
    string internal constant WHERE_TO_FIND_TERMS =
        "Terms and conditions can be found by calling getTerms() on the Keepers contract.";
}

File 55 of 57 : SolidStateDiamondRevokableUpgradability.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.18;

import { IOwnable, Ownable, OwnableInternal } from "@solidstate/contracts/access/ownable/Ownable.sol";
import { ISafeOwnable, SafeOwnable } from "@solidstate/contracts/access/ownable/SafeOwnable.sol";
import { IERC165 } from "@solidstate/contracts/interfaces/IERC165.sol";
import { IERC173 } from "@solidstate/contracts/interfaces/IERC173.sol";
import { ERC165Base, ERC165BaseStorage } from "@solidstate/contracts/introspection/ERC165/base/ERC165Base.sol";
import { DiamondBase } from "@solidstate/contracts/proxy/diamond/base/DiamondBase.sol";
import { DiamondFallback, IDiamondFallback } from "@solidstate/contracts/proxy/diamond/fallback/DiamondFallback.sol";
import { DiamondReadable, IDiamondReadable } from "@solidstate/contracts/proxy/diamond/readable/DiamondReadable.sol";
import { IDiamondWritable } from "@solidstate/contracts/proxy/diamond/writable/DiamondWritable.sol";
import { DiamondWritableRevokable } from "./facets/DiamondWritableRevokable/DiamondWritableRevokable.sol";
import { ISolidStateDiamond } from "@solidstate/contracts/proxy/diamond/ISolidStateDiamond.sol";

/**
 * @title SolidState "Diamond" proxy reference implementation with DiamondWritableRevokable
 */
abstract contract SolidStateDiamondRevokableUpgradability is
    ISolidStateDiamond,
    DiamondBase,
    DiamondFallback,
    DiamondReadable,
    DiamondWritableRevokable,
    SafeOwnable,
    ERC165Base
{
    constructor() {
        bytes4[] memory selectors = new bytes4[](12);
        uint256 selectorIndex;

        // register DiamondFallback

        selectors[selectorIndex++] = IDiamondFallback.getFallbackAddress.selector;
        selectors[selectorIndex++] = IDiamondFallback.setFallbackAddress.selector;

        _setSupportsInterface(type(IDiamondFallback).interfaceId, true);

        // register DiamondWritable

        selectors[selectorIndex++] = IDiamondWritable.diamondCut.selector;

        _setSupportsInterface(type(IDiamondWritable).interfaceId, true);

        // register DiamondReadable

        selectors[selectorIndex++] = IDiamondReadable.facets.selector;
        selectors[selectorIndex++] = IDiamondReadable.facetFunctionSelectors.selector;
        selectors[selectorIndex++] = IDiamondReadable.facetAddresses.selector;
        selectors[selectorIndex++] = IDiamondReadable.facetAddress.selector;

        _setSupportsInterface(type(IDiamondReadable).interfaceId, true);

        // register ERC165

        selectors[selectorIndex++] = IERC165.supportsInterface.selector;

        _setSupportsInterface(type(IERC165).interfaceId, true);

        // register SafeOwnable
        selectors[selectorIndex++] = Ownable.owner.selector;
        selectors[selectorIndex++] = SafeOwnable.nomineeOwner.selector;
        selectors[selectorIndex++] = Ownable.transferOwnership.selector;
        selectors[selectorIndex++] = SafeOwnable.acceptOwnership.selector;

        _setSupportsInterface(type(IERC173).interfaceId, true);

        // diamond cut

        FacetCut[] memory facetCuts = new FacetCut[](1);

        facetCuts[0] = FacetCut({ target: address(this), action: FacetCutAction.ADD, selectors: selectors });

        _diamondCut(facetCuts, address(0), "");

        // set owner

        _setOwner(msg.sender);
    }

    receive() external payable {}

    function _transferOwnership(address account) internal virtual override(OwnableInternal, SafeOwnable) {
        super._transferOwnership(account);
    }

    /**
     * @inheritdoc DiamondFallback
     */
    function _getImplementation()
        internal
        view
        override(DiamondBase, DiamondFallback)
        returns (address implementation)
    {
        implementation = super._getImplementation();
    }
}

File 56 of 57 : IOperatorFilterRegistry.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

interface IOperatorFilterRegistry {
    /**
     * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns
     *         true if supplied registrant address is not registered.
     */
    function isOperatorAllowed(address registrant, address operator) external view returns (bool);

    /**
     * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.
     */
    function register(address registrant) external;

    /**
     * @notice Registers an address with the registry and "subscribes" to another address's filtered operators and codeHashes.
     */
    function registerAndSubscribe(address registrant, address subscription) external;

    /**
     * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another
     *         address without subscribing.
     */
    function registerAndCopyEntries(address registrant, address registrantToCopy) external;

    /**
     * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.
     *         Note that this does not remove any filtered addresses or codeHashes.
     *         Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.
     */
    function unregister(address addr) external;

    /**
     * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered.
     */
    function updateOperator(address registrant, address operator, bool filtered) external;

    /**
     * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.
     */
    function updateOperators(address registrant, address[] calldata operators, bool filtered) external;

    /**
     * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.
     */
    function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external;

    /**
     * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.
     */
    function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external;

    /**
     * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous
     *         subscription if present.
     *         Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,
     *         subscriptions will not be forwarded. Instead the former subscription's existing entries will still be
     *         used.
     */
    function subscribe(address registrant, address registrantToSubscribe) external;

    /**
     * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.
     */
    function unsubscribe(address registrant, bool copyExistingEntries) external;

    /**
     * @notice Get the subscription address of a given registrant, if any.
     */
    function subscriptionOf(address addr) external returns (address registrant);

    /**
     * @notice Get the set of addresses subscribed to a given registrant.
     *         Note that order is not guaranteed as updates are made.
     */
    function subscribers(address registrant) external returns (address[] memory);

    /**
     * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.
     *         Note that order is not guaranteed as updates are made.
     */
    function subscriberAt(address registrant, uint256 index) external returns (address);

    /**
     * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.
     */
    function copyEntriesOf(address registrant, address registrantToCopy) external;

    /**
     * @notice Returns true if operator is filtered by a given address or its subscription.
     */
    function isOperatorFiltered(address registrant, address operator) external returns (bool);

    /**
     * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription.
     */
    function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);

    /**
     * @notice Returns true if a codeHash is filtered by a given address or its subscription.
     */
    function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);

    /**
     * @notice Returns a list of filtered operators for a given address or its subscription.
     */
    function filteredOperators(address addr) external returns (address[] memory);

    /**
     * @notice Returns the set of filtered codeHashes for a given address or its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredCodeHashes(address addr) external returns (bytes32[] memory);

    /**
     * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or
     *         its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredOperatorAt(address registrant, uint256 index) external returns (address);

    /**
     * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or
     *         its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);

    /**
     * @notice Returns true if an address has registered
     */
    function isRegistered(address addr) external returns (bool);

    /**
     * @dev Convenience method to compute the code hash of an arbitrary contract
     */
    function codeHashOf(address addr) external returns (bytes32);
}

File 57 of 57 : Constants.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

address constant CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS = 0x000000000000AAeB6D7670E522A718067333cd4E;
address constant CANONICAL_CORI_SUBSCRIPTION = 0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6;

Settings
{
  "metadata": {
    "bytecodeHash": "none"
  },
  "optimizer": {
    "enabled": true,
    "runs": 800
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"string","name":"baseURI_","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"DiamondWritable__InvalidInitializationParameters","type":"error"},{"inputs":[],"name":"DiamondWritable__RemoveTargetNotZeroAddress","type":"error"},{"inputs":[],"name":"DiamondWritable__ReplaceTargetIsIdentical","type":"error"},{"inputs":[],"name":"DiamondWritable__SelectorAlreadyAdded","type":"error"},{"inputs":[],"name":"DiamondWritable__SelectorIsImmutable","type":"error"},{"inputs":[],"name":"DiamondWritable__SelectorNotFound","type":"error"},{"inputs":[],"name":"DiamondWritable__SelectorNotSpecified","type":"error"},{"inputs":[],"name":"DiamondWritable__TargetHasNoCode","type":"error"},{"inputs":[],"name":"ERC165Base__InvalidInterfaceId","type":"error"},{"inputs":[],"name":"Ownable__NotOwner","type":"error"},{"inputs":[],"name":"Ownable__NotTransitiveOwner","type":"error"},{"inputs":[],"name":"Proxy__ImplementationIsNotContract","type":"error"},{"inputs":[],"name":"SafeOwnable__NotNomineeOwner","type":"error"},{"inputs":[],"name":"UpgradeabilityRevoked","type":"error"},{"anonymous":false,"inputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"enum IDiamondWritableInternal.FacetCutAction","name":"action","type":"uint8"},{"internalType":"bytes4[]","name":"selectors","type":"bytes4[]"}],"indexed":false,"internalType":"struct IDiamondWritableInternal.FacetCut[]","name":"facetCuts","type":"tuple[]"},{"indexed":false,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"DiamondCut","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"enum IDiamondWritableInternal.FacetCutAction","name":"action","type":"uint8"},{"internalType":"bytes4[]","name":"selectors","type":"bytes4[]"}],"internalType":"struct IDiamondWritableInternal.FacetCut[]","name":"facetCuts","type":"tuple[]"},{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"diamondCut","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"selector","type":"bytes4"}],"name":"facetAddress","outputs":[{"internalType":"address","name":"facet","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"facetAddresses","outputs":[{"internalType":"address[]","name":"addresses","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"facet","type":"address"}],"name":"facetFunctionSelectors","outputs":[{"internalType":"bytes4[]","name":"selectors","type":"bytes4[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"facets","outputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes4[]","name":"selectors","type":"bytes4[]"}],"internalType":"struct IDiamondReadable.Facet[]","name":"diamondFacets","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFallbackAddress","outputs":[{"internalType":"address","name":"fallbackAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nomineeOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"fallbackAddress","type":"address"}],"name":"setFallbackAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60806040523480156200001157600080fd5b506040516200354738038062003547833981016040819052620000349162001362565b60408051600c8082526101a0820190925260009160208201610180803683370190505090506000632c40805960e01b82826200007081620013f3565b9350815181106200008557620000856200141b565b6001600160e01b031990921660209283029190910190910152639142376560e01b8282620000b381620013f3565b935081518110620000c857620000c86200141b565b6001600160e01b031990921660209283029190910190910152620000f5632f40adcf60e21b6001620006d8565b6307e4c70760e21b82826200010a81620013f3565b9350815181106200011f576200011f6200141b565b6001600160e01b0319909216602092830291909101909101526200014c6307e4c70760e21b6001620006d8565b637a0ed62760e01b82826200016181620013f3565b9350815181106200017657620001766200141b565b6001600160e01b0319909216602092830291909101909101526356fe50af60e11b8282620001a481620013f3565b935081518110620001b957620001b96200141b565b6001600160e01b0319909216602092830291909101909101526314bbdacb60e21b8282620001e781620013f3565b935081518110620001fc57620001fc6200141b565b6001600160e01b0319909216602092830291909101909101526366ffd66360e11b82826200022a81620013f3565b9350815181106200023f576200023f6200141b565b6001600160e01b0319909216602092830291909101909101526200026c6348e2b09360e01b6001620006d8565b6301ffc9a760e01b82826200028181620013f3565b9350815181106200029657620002966200141b565b6001600160e01b031990921660209283029190910190910152620002c36301ffc9a760e01b6001620006d8565b638da5cb5b60e01b8282620002d881620013f3565b935081518110620002ed57620002ed6200141b565b6001600160e01b03199092166020928302919091019091015263455a8a8560e11b82826200031b81620013f3565b9350815181106200033057620003306200141b565b6001600160e01b03199092166020928302919091019091015263f2fde38b60e01b82826200035e81620013f3565b9350815181106200037357620003736200141b565b6001600160e01b0319909216602092830291909101909101526379ba509760e01b8282620003a181620013f3565b935081518110620003b657620003b66200141b565b6001600160e01b031990921660209283029190910190910152620003e36307f5828d60e41b6001620006d8565b604080516001808252818301909252600091816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081620003fa579050506040805160608101909152308152909150602081016000815260200184815250816000815181106200046057620004606200141b565b60200260200101819052506200048e816000604051806020016040528060008152506200074a60201b60201c565b620004993362000926565b505050620004b66380ac58cd60e01b6001620006d860201b60201c565b620004ca63780e9d6360e01b6001620006d8565b620004de63152a902d60e11b6001620006d8565b6200050a7f4f355d889785bcc16cc9d90e75bf97878cb8011983020de308d470c8cedf3f21336200099a565b620005367fe3318284dc7df61884a0f44a9db7f6ed140b100c862cbc07f3e8c1de3407f745336200099a565b6102bc6200054e62000a1060201b62000d111760201c565b60010160006101000a81548161ffff021916908361ffff160217905550336200058162000a1060201b62000d111760201c565b60030160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550600a620005bf62000a3460201b62000d351760201c565b60030160026101000a81548161ffff021916908361ffff160217905550614e20620005f462000a3460201b62000d351760201c565b60030160006101000a81548161ffff021916908361ffff160217905550826200062762000a5860201b62000d591760201c565b90620006349082620014d5565b50816200064b62000a5860201b62000d591760201c565b600101906200065b9082620014d5565b50806200067262000a5860201b62000d591760201c565b60020190620006829082620014d5565b50620006b06200069c62000a7c60201b62000d7d1760201c565b60010162000aa060201b62000da11760201c565b620006cf733cc6cdda760b79bafa08df41ecfa224f810dceb662000aa9565b5050506200171f565b6001600160e01b03198083169003620007045760405163b0a19dd560e01b815260040160405180910390fd5b806200071a62000ba960201b62000daa1760201c565b6001600160e01b03199390931660009081526020939093526040909220805460ff19169215159290921790915550565b60006200076162000bcd60201b62000dce1760201c565b600181015490915061ffff811690819060009060071615620007955750600381901c60009081526002840160205260409020545b60005b875181101562000894576000888281518110620007b957620007b96200141b565b60200260200101519050600081602001519050816040015151600003620007f35760405163eb6c3aeb60e01b815260040160405180910390fd5b60008160028111156200080a576200080a62001431565b0362000829576200081e8786868562000bf1565b909550935062000889565b600181600281111562000840576200084062001431565b03620008585762000852878362000d50565b62000889565b60028160028111156200086f576200086f62001431565b036200088957620008838786868562000eb6565b90955093505b505060010162000798565b50828214620008b15760018401805461ffff191661ffff84161790555b6007821615620008d457600382901c600090815260028501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516200090993929190620015cf565b60405180910390a16200091d8686620010e2565b50505050505050565b60006200093d620011e360201b62000df21760201c565b80546040519192506001600160a01b03808516929116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a380546001600160a01b0319166001600160a01b0392909216919091179055565b620009d381620009b46200120760201b62000e161760201c565b6000858152602091825260409020919062000e3a6200122b821b17901c565b5060405133906001600160a01b0383169084907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d90600090a45050565b7ff298352fd56f58214bf2245c2b202523f72fca3199077ce992640958228b281f90565b7f7e2d07d64a14e19cbb404a97c70a37424fe26c0b914348bf23e7cf52a012c2eb90565b7f99574a7094154bb123ae6ae102096f0bf9679b85a5cd1e727aaa0ae5f132e6b190565b7f5c326f5dbb0f8295b6973e9519c6a49d522fd1c150da562fee87f19638cabf3090565b80546001019055565b6daaeb6d7670e522a718067333cd4e3b1562000ba65760405163c3c5a54760e01b81523060048201526daaeb6d7670e522a718067333cd4e9063c3c5a547906024016020604051808303816000875af115801562000b0b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000b319190620016d6565b62000ba657604051633e9f1edf60e11b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e90637d3e3dbe90604401600060405180830381600087803b15801562000b8c57600080fd5b505af115801562000ba1573d6000803e3d6000fd5b505050505b50565b7ffc606c433378e3a7e0a6a531deac289b66caa1b4aa8554fd4ab2c6f1570f92d890565b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9390565b805160009081906001600160a01b0316301480159062000c31575062000c2f83600001516001600160a01b03166200124b60201b620003061760201c565b155b1562000c5057604051633ddc5cab60e21b815260040160405180910390fd5b60005b83604001515181101562000d435760008460400151828151811062000c7c5762000c7c6200141b565b6020908102919091018101516001600160e01b031981166000908152918a9052604090912054909150606081901c1562000cc957604051634923a77160e11b815260040160405180910390fd5b85516001600160e01b0319838116600081815260208d90526040902060609390931b6001600160601b0319168b1790925560058a901b60e090811692831c91831c1999909916179781900362000d3357600389901c600090815260028b0160205260408120989098555b5050506001958601950162000c53565b5093959294509192505050565b62000d7381600001516001600160a01b03166200124b60201b620003061760201c565b62000d9157604051633ddc5cab60e21b815260040160405180910390fd5b60005b81604001515181101562000eb15760008260400151828151811062000dbd5762000dbd6200141b565b6020908102919091018101516001600160e01b03198116600090815291869052604090912054909150606081901c8062000e0a576040516337e25a9760e11b815260040160405180910390fd5b306001600160a01b0382160362000e345760405163e983573160e01b815260040160405180910390fd5b84600001516001600160a01b0316816001600160a01b03160362000e6b576040516330baabf360e11b815260040160405180910390fd5b5083516001600160e01b031992909216600090815260208690526040902060609290921b6001600160601b0319166001600160601b039190911617905560010162000d94565b505050565b805160009081906001600160a01b03161562000ee557604051633ab3490960e21b815260040160405180910390fd5b600385901c6007861660005b856040015151811015620010ce5760008660400151828151811062000f1a5762000f1a6200141b565b6020908102919091018101516001600160e01b031981166000908152918c9052604090912054909150606081901c62000f66576040516337e25a9760e11b815260040160405180910390fd5b30606082901c0362000f8b5760405163e983573160e01b815260040160405180910390fd5b600089900362000fb957600019909401600081815260028c0160205260409020549850936007935062000fc1565b600019909301925b600584901b89901b6000806001600160e01b03198084169086161462001014576001600160e01b03198316600090815260208f90526040902080546001600160601b0319166001600160601b0386161790555b50506001600160e01b03198316600090815260208d90526040812055611fff600383901c1660e0600584901b168782146200107957600082815260028f016020526040902080546001600160e01b031980841c19909116908516831c1790556200109d565b80836001600160e01b031916901c816001600160e01b031960001b901c198d16179b505b86600003620010bc57600088815260028f01602052604081208190559b505b50506001909301925062000ef1915050565b5060039190911b1796939550929350505050565b8051156001600160a01b03831615146200110f576040516326df4ccd60e01b815260040160405180910390fd5b6001600160a01b03821615620011df576001600160a01b03821630146200116d576200114f826001600160a01b03166200124b60201b620003061760201c565b6200116d57604051633ddc5cab60e21b815260040160405180910390fd5b6000826001600160a01b03168260405162001189919062001701565b600060405180830381855af49150503d8060008114620011c6576040519150601f19603f3d011682016040523d82523d6000602084013e620011cb565b606091505b505090508062000eb1573d6000803e3d6000fd5b5050565b7f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046090565b7fd3889cc5458b268d0544e5534672df1296288ca3f93cbd39bd6f497a5c62281190565b600062001242836001600160a01b03841662001251565b90505b92915050565b3b151590565b600081815260018301602052604081205462001245575081546001808201845560008481526020808220909301849055845493815293810190915260409092205590565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620012c8578181015183820152602001620012ae565b50506000910152565b600082601f830112620012e357600080fd5b81516001600160401b038082111562001300576200130062001295565b604051601f8301601f19908116603f011681019082821181831017156200132b576200132b62001295565b816040528381528660208588010111156200134557600080fd5b62001358846020830160208901620012ab565b9695505050505050565b6000806000606084860312156200137857600080fd5b83516001600160401b03808211156200139057600080fd5b6200139e87838801620012d1565b94506020860151915080821115620013b557600080fd5b620013c387838801620012d1565b93506040860151915080821115620013da57600080fd5b50620013e986828701620012d1565b9150509250925092565b6000600182016200141457634e487b7160e01b600052601160045260246000fd5b5060010190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b600181811c908216806200145c57607f821691505b6020821081036200147d57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000eb157600081815260208120601f850160051c81016020861015620014ac5750805b601f850160051c820191505b81811015620014cd57828155600101620014b8565b505050505050565b81516001600160401b03811115620014f157620014f162001295565b620015098162001502845462001447565b8462001483565b602080601f831160018114620015415760008415620015285750858301515b600019600386901b1c1916600185901b178555620014cd565b600085815260208120601f198616915b82811015620015725788860151825594840194600190910190840162001551565b5085821015620015915787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008151808452620015bb816020860160208601620012ab565b601f01601f19169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b84811015620016a457898403607f19018652815180516001600160a01b031685528381015189860190600381106200164057634e487b7160e01b600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156200168e5783516001600160e01b031916825292860192600192909201919086019062001662565b50978501979550505090820190600101620015f8565b50506001600160a01b038a16908801528681036040880152620016c88189620015a1565b9a9950505050505050505050565b600060208284031215620016e957600080fd5b81518015158114620016fa57600080fd5b9392505050565b6000825162001715818460208701620012ab565b9190910192915050565b611e18806200172f6000396000f3fe6080604052600436106100cb5760003560e01c80638ab5150a11610074578063adfca15e1161004e578063adfca15e14610251578063cdffacc61461027e578063f2fde38b146102d7576100d2565b80638ab5150a146102075780638da5cb5b1461021c5780639142376514610231576100d2565b806352ef6b2c116100a557806352ef6b2c146101ae57806379ba5097146101d05780637a0ed627146101e5576100d2565b806301ffc9a71461012c5780631f931c1c146101615780632c40805914610181576100d2565b366100d257005b60006100dc6102f7565b90506001600160a01b0381163b610106576040516321f27f0d60e21b815260040160405180910390fd5b3660008037600080366000845af43d6000803e808015610125573d6000f35b3d6000fd5b005b34801561013857600080fd5b5061014c6101473660046117fb565b61030c565b60405190151581526020015b60405180910390f35b34801561016d57600080fd5b5061012a61017c366004611876565b61034f565b34801561018d57600080fd5b5061019661041c565b6040516001600160a01b039091168152602001610158565b3480156101ba57600080fd5b506101c361044f565b6040516101589190611928565b3480156101dc57600080fd5b5061012a610625565b3480156101f157600080fd5b506101fa610668565b60405161015891906119ba565b34801561021357600080fd5b50610196610ac3565b34801561022857600080fd5b50610196610acd565b34801561023d57600080fd5b5061012a61024c366004611a37565b610ad7565b34801561025d57600080fd5b5061027161026c366004611a37565b610b50565b6040516101589190611a52565b34801561028a57600080fd5b506101966102993660046117fb565b6001600160e01b03191660009081527f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc93602052604090205460601c90565b3480156102e357600080fd5b5061012a6102f2366004611a37565b610ccf565b6000610301610e56565b905090565b3b151590565b6001600160e01b0319811660009081527ffc606c433378e3a7e0a6a531deac289b66caa1b4aa8554fd4ab2c6f1570f92d8602052604081205460ff165b92915050565b610357610ec9565b6001600160a01b0316336001600160a01b03161461038857604051632f7a8ee160e01b815260040160405180910390fd5b7f245a6202ca3febd67bba5bd3d626122408bcacfedfba95bee54d5418459da8505460ff16156103cb5760405163ba5b67b960e01b815260040160405180910390fd5b6104156103d88587611b28565b8484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610efc92505050565b5050505050565b60006103017f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc96546001600160a01b031690565b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc94546060907f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc939061ffff1667ffffffffffffffff8111156104b2576104b2611a94565b6040519080825280602002602001820160405280156104db578160200160208202803683370190505b50915060008060005b600184015461ffff1682101561061d576000818152600285016020526040812054905b6008811015610608578361051a81611c72565b600188015490955061ffff168511905061060857600581901b82901b6001600160e01b0319811660009081526020889052604081205460601c90805b888110156105ab578a818151811061057057610570611c8b565b60200260200101516001600160a01b0316836001600160a01b03160361059957600191506105ab565b806105a381611c72565b915050610556565b5080156105ba575050506105f6565b818a89815181106105cd576105cd611c8b565b6001600160a01b0390921660209283029190910190910152876105ef81611c72565b9850505050505b8061060081611c72565b915050610507565b5050808061061590611c72565b9150506104e4565b505082525090565b61062d6110dc565b6001600160a01b0316336001600160a01b03161461065e5760405163efd1052d60e01b815260040160405180910390fd5b610666611104565b565b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc94546060907f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc939061ffff1667ffffffffffffffff8111156106cb576106cb611a94565b60405190808252806020026020018201604052801561071157816020015b6040805180820190915260008152606060208201528152602001906001900390816106e95790505b50600182015490925060009061ffff1667ffffffffffffffff81111561073957610739611a94565b604051908082528060200260200182016040528015610762578160200160208202803683370190505b50905060008060005b600185015461ffff16821015610a51576000818152600286016020526040812054905b6008811015610a3c57836107a181611c72565b600189015490955061ffff1685119050610a3c57600581901b82901b6001600160e01b0319811660009081526020899052604081205460601c90805b888110156108fa57826001600160a01b03168c828151811061080157610801611c8b565b6020026020010151600001516001600160a01b0316036108e857838c828151811061082e5761082e611c8b565b6020026020010151602001518b838151811061084c5761084c611c8b565b602002602001015160ff168151811061086757610867611c8b565b60200260200101906001600160e01b03191690816001600160e01b0319168152505060ff8a828151811061089d5761089d611c8b565b602002602001015160ff16106108b257600080fd5b8981815181106108c4576108c4611c8b565b6020026020010180518091906108d990611ca1565b60ff16905250600191506108fa565b806108f281611c72565b9150506107dd565b50801561090957505050610a2a565b818b898151811061091c5761091c611c8b565b60209081029190910101516001600160a01b03909116905260018a015461ffff1667ffffffffffffffff81111561095557610955611a94565b60405190808252806020026020018201604052801561097e578160200160208202803683370190505b508b898151811061099157610991611c8b565b602002602001015160200181905250828b89815181106109b3576109b3611c8b565b6020026020010151602001516000815181106109d1576109d1611c8b565b60200260200101906001600160e01b03191690816001600160e01b031916815250506001898981518110610a0757610a07611c8b565b60ff9092166020928302919091019091015287610a2381611c72565b9850505050505b80610a3481611c72565b91505061078e565b50508080610a4990611c72565b91505061076b565b5060005b82811015610ab8576000848281518110610a7157610a71611c8b565b602002602001015160ff1690506000878381518110610a9257610a92611c8b565b602002602001015160200151905081815250508080610ab090611c72565b915050610a55565b508185525050505090565b60006103016110dc565b6000610301610ec9565b610adf610ec9565b6001600160a01b0316336001600160a01b031614610b1057604051632f7a8ee160e01b815260040160405180910390fd5b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9680546001600160a01b0319166001600160a01b03831617905550565b50565b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc94546060907f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc939061ffff1667ffffffffffffffff811115610bb357610bb3611a94565b604051908082528060200260200182016040528015610bdc578160200160208202803683370190505b50915060008060005b600184015461ffff16821015610cc5576000818152600285016020526040812054905b6008811015610cb05783610c1b81611c72565b600188015490955061ffff1685119050610cb057600581901b82901b6001600160e01b0319811660009081526020889052604090205460601c6001600160a01b038a1603610c9d5780888781518110610c7657610c76611c8b565b6001600160e01b03199092166020928302919091019091015285610c9981611c72565b9650505b5080610ca881611c72565b915050610c08565b50508080610cbd90611c72565b915050610be5565b5050825250919050565b610cd7610ec9565b6001600160a01b0316336001600160a01b031614610d0857604051632f7a8ee160e01b815260040160405180910390fd5b610b4d8161113e565b7ff298352fd56f58214bf2245c2b202523f72fca3199077ce992640958228b281f90565b7f7e2d07d64a14e19cbb404a97c70a37424fe26c0b914348bf23e7cf52a012c2eb90565b7f99574a7094154bb123ae6ae102096f0bf9679b85a5cd1e727aaa0ae5f132e6b190565b7f5c326f5dbb0f8295b6973e9519c6a49d522fd1c150da562fee87f19638cabf3090565b80546001019055565b7ffc606c433378e3a7e0a6a531deac289b66caa1b4aa8554fd4ab2c6f1570f92d890565b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9390565b7f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046090565b7fd3889cc5458b268d0544e5534672df1296288ca3f93cbd39bd6f497a5c62281190565b6000610e4f836001600160a01b038416611181565b9392505050565b600080356001600160e01b03191681527f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc93602052604090205460601c80610ec657507f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc96546001600160a01b031690565b90565b60007f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f6716804605b546001600160a01b0316919050565b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc94547f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc939061ffff811690819060009060071615610f6b5750600381901c60009081526002840160205260409020545b60005b8751811015611050576000888281518110610f8b57610f8b611c8b565b60200260200101519050600081602001519050816040015151600003610fc45760405163eb6c3aeb60e01b815260040160405180910390fd5b6000816002811115610fd857610fd8611cc0565b03610ff357610fe9878686856111c4565b9095509350611046565b600181600281111561100757611007611cc0565b0361101b576110168783611308565b611046565b600281600281111561102f5761102f611cc0565b036110465761104087868685611458565b90955093505b5050600101610f6e565b5082821461106c5760018401805461ffff191661ffff84161790555b600782161561108e57600382901c600090815260028501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516110c193929190611d26565b60405180910390a16110d38686611680565b50505050505050565b60007f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce6617890610eed565b61110d33611764565b7f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce661789080546001600160a01b0319169055565b7f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce661789080546001600160a01b0319166001600160a01b038316179055610b4d81818181565b6000818152600183016020526040812054610349575081546001808201845560008481526020808220909301849055845493815293810190915260409092205590565b805160009081906001600160a01b031630148015906111ec575082516001600160a01b03163b155b1561120a57604051633ddc5cab60e21b815260040160405180910390fd5b60005b8360400151518110156112fb5760008460400151828151811061123257611232611c8b565b6020908102919091018101516001600160e01b031981166000908152918a9052604090912054909150606081901c1561127e57604051634923a77160e11b815260040160405180910390fd5b85516001600160e01b0319838116600081815260208d90526040902060609390931b6bffffffffffffffffffffffff19168b1790925560058a901b60e090811692831c91831c199990991617978190036112ec57600389901c600090815260028b0160205260408120989098555b5050506001958601950161120d565b5093959294509192505050565b80516001600160a01b03163b61133157604051633ddc5cab60e21b815260040160405180910390fd5b60005b8160400151518110156114535760008260400151828151811061135957611359611c8b565b6020908102919091018101516001600160e01b03198116600090815291869052604090912054909150606081901c806113a5576040516337e25a9760e11b815260040160405180910390fd5b306001600160a01b038216036113ce5760405163e983573160e01b815260040160405180910390fd5b84600001516001600160a01b0316816001600160a01b031603611404576040516330baabf360e11b815260040160405180910390fd5b5083516001600160e01b031992909216600090815260208690526040902060609290921b6bffffffffffffffffffffffff19166bffffffffffffffffffffffff91909116179055600101611334565b505050565b805160009081906001600160a01b03161561148657604051633ab3490960e21b815260040160405180910390fd5b600385901c6007861660005b85604001515181101561166c576000866040015182815181106114b7576114b7611c8b565b6020908102919091018101516001600160e01b031981166000908152918c9052604090912054909150606081901c611502576040516337e25a9760e11b815260040160405180910390fd5b30606082901c036115265760405163e983573160e01b815260040160405180910390fd5b600089900361155257600019909401600081815260028c0160205260409020549850936007935061155a565b600019909301925b600584901b89901b6000806001600160e01b0319808416908616146115b6576001600160e01b03198316600090815260208f90526040902080546bffffffffffffffffffffffff19166bffffffffffffffffffffffff86161790555b50506001600160e01b03198316600090815260208d90526040812055611fff600383901c1660e0600584901b1687821461161957600082815260028f016020526040902080546001600160e01b031980841c19909116908516831c17905561163d565b80836001600160e01b031916901c816001600160e01b031960001b901c198d16179b505b8660000361165b57600088815260028f01602052604081208190559b505b505060019093019250611492915050565b5060039190911b1796939550929350505050565b8051156001600160a01b03831615146116ac576040516326df4ccd60e01b815260040160405180910390fd5b6001600160a01b03821615611760576001600160a01b03821630146116f3576001600160a01b0382163b6116f357604051633ddc5cab60e21b815260040160405180910390fd5b6000826001600160a01b03168260405161170d9190611def565b600060405180830381855af49150503d8060008114611748576040519150601f19603f3d011682016040523d82523d6000602084013e61174d565b606091505b5050905080611453573d6000803e3d6000fd5b5050565b7f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046080546040516001600160a01b038481169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a380546001600160a01b0319166001600160a01b0392909216919091179055565b80356001600160e01b0319811681146117f657600080fd5b919050565b60006020828403121561180d57600080fd5b610e4f826117de565b80356001600160a01b03811681146117f657600080fd5b60008083601f84011261183f57600080fd5b50813567ffffffffffffffff81111561185757600080fd5b60208301915083602082850101111561186f57600080fd5b9250929050565b60008060008060006060868803121561188e57600080fd5b853567ffffffffffffffff808211156118a657600080fd5b818801915088601f8301126118ba57600080fd5b8135818111156118c957600080fd5b8960208260051b85010111156118de57600080fd5b602083019750809650506118f460208901611816565b9450604088013591508082111561190a57600080fd5b506119178882890161182d565b969995985093965092949392505050565b6020808252825182820181905260009190848201906040850190845b818110156119695783516001600160a01b031683529284019291840191600101611944565b50909695505050505050565b600081518084526020808501945080840160005b838110156119af5781516001600160e01b03191687529582019590820190600101611989565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b83811015611a2957888303603f19018552815180516001600160a01b03168452870151878401879052611a1687850182611975565b95880195935050908601906001016119e1565b509098975050505050505050565b600060208284031215611a4957600080fd5b610e4f82611816565b6020808252825182820181905260009190848201906040850190845b818110156119695783516001600160e01b03191683529284019291840191600101611a6e565b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715611acd57611acd611a94565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715611afc57611afc611a94565b604052919050565b600067ffffffffffffffff821115611b1e57611b1e611a94565b5060051b60200190565b6000611b3b611b3684611b04565b611ad3565b83815260208082019190600586811b860136811115611b5957600080fd5b865b81811015611c4f57803567ffffffffffffffff80821115611b7c5760008081fd5b818a01915060608236031215611b925760008081fd5b611b9a611aaa565b611ba383611816565b81528683013560038110611bb75760008081fd5b8188015260408381013583811115611bcf5760008081fd5b939093019236601f850112611be657600092508283fd5b83359250611bf6611b3684611b04565b83815292871b84018801928881019036851115611c135760008081fd5b948901945b84861015611c3857611c29866117de565b82529489019490890190611c18565b918301919091525088525050948301948301611b5b565b5092979650505050505050565b634e487b7160e01b600052601160045260246000fd5b600060018201611c8457611c84611c5c565b5060010190565b634e487b7160e01b600052603260045260246000fd5b600060ff821660ff8103611cb757611cb7611c5c565b60010192915050565b634e487b7160e01b600052602160045260246000fd5b60005b83811015611cf1578181015183820152602001611cd9565b50506000910152565b60008151808452611d12816020860160208601611cd6565b601f01601f19169290920160200192915050565b6000606080830181845280875180835260808601915060808160051b87010192506020808a016000805b84811015611dbf57898703607f19018652825180516001600160a01b031688528481015160038110611d9057634e487b7160e01b84526021600452602484fd5b88860152604090810151908801899052611dac89890182611975565b9750509483019491830191600101611d50565b5050506001600160a01b0389169087015250508381036040850152611de48186611cfa565b979650505050505050565b60008251611e01818460208701611cd6565b919091019291505056fea164736f6c6343000812000a000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000074b6565706572730000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064b45455045520000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003068747470733a2f2f6b6565706572732d746f6b656e2d6d657461646174612e73332e616d617a6f6e6177732e636f6d2f00000000000000000000000000000000

Deployed Bytecode

0x6080604052600436106100cb5760003560e01c80638ab5150a11610074578063adfca15e1161004e578063adfca15e14610251578063cdffacc61461027e578063f2fde38b146102d7576100d2565b80638ab5150a146102075780638da5cb5b1461021c5780639142376514610231576100d2565b806352ef6b2c116100a557806352ef6b2c146101ae57806379ba5097146101d05780637a0ed627146101e5576100d2565b806301ffc9a71461012c5780631f931c1c146101615780632c40805914610181576100d2565b366100d257005b60006100dc6102f7565b90506001600160a01b0381163b610106576040516321f27f0d60e21b815260040160405180910390fd5b3660008037600080366000845af43d6000803e808015610125573d6000f35b3d6000fd5b005b34801561013857600080fd5b5061014c6101473660046117fb565b61030c565b60405190151581526020015b60405180910390f35b34801561016d57600080fd5b5061012a61017c366004611876565b61034f565b34801561018d57600080fd5b5061019661041c565b6040516001600160a01b039091168152602001610158565b3480156101ba57600080fd5b506101c361044f565b6040516101589190611928565b3480156101dc57600080fd5b5061012a610625565b3480156101f157600080fd5b506101fa610668565b60405161015891906119ba565b34801561021357600080fd5b50610196610ac3565b34801561022857600080fd5b50610196610acd565b34801561023d57600080fd5b5061012a61024c366004611a37565b610ad7565b34801561025d57600080fd5b5061027161026c366004611a37565b610b50565b6040516101589190611a52565b34801561028a57600080fd5b506101966102993660046117fb565b6001600160e01b03191660009081527f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc93602052604090205460601c90565b3480156102e357600080fd5b5061012a6102f2366004611a37565b610ccf565b6000610301610e56565b905090565b3b151590565b6001600160e01b0319811660009081527ffc606c433378e3a7e0a6a531deac289b66caa1b4aa8554fd4ab2c6f1570f92d8602052604081205460ff165b92915050565b610357610ec9565b6001600160a01b0316336001600160a01b03161461038857604051632f7a8ee160e01b815260040160405180910390fd5b7f245a6202ca3febd67bba5bd3d626122408bcacfedfba95bee54d5418459da8505460ff16156103cb5760405163ba5b67b960e01b815260040160405180910390fd5b6104156103d88587611b28565b8484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610efc92505050565b5050505050565b60006103017f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc96546001600160a01b031690565b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc94546060907f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc939061ffff1667ffffffffffffffff8111156104b2576104b2611a94565b6040519080825280602002602001820160405280156104db578160200160208202803683370190505b50915060008060005b600184015461ffff1682101561061d576000818152600285016020526040812054905b6008811015610608578361051a81611c72565b600188015490955061ffff168511905061060857600581901b82901b6001600160e01b0319811660009081526020889052604081205460601c90805b888110156105ab578a818151811061057057610570611c8b565b60200260200101516001600160a01b0316836001600160a01b03160361059957600191506105ab565b806105a381611c72565b915050610556565b5080156105ba575050506105f6565b818a89815181106105cd576105cd611c8b565b6001600160a01b0390921660209283029190910190910152876105ef81611c72565b9850505050505b8061060081611c72565b915050610507565b5050808061061590611c72565b9150506104e4565b505082525090565b61062d6110dc565b6001600160a01b0316336001600160a01b03161461065e5760405163efd1052d60e01b815260040160405180910390fd5b610666611104565b565b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc94546060907f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc939061ffff1667ffffffffffffffff8111156106cb576106cb611a94565b60405190808252806020026020018201604052801561071157816020015b6040805180820190915260008152606060208201528152602001906001900390816106e95790505b50600182015490925060009061ffff1667ffffffffffffffff81111561073957610739611a94565b604051908082528060200260200182016040528015610762578160200160208202803683370190505b50905060008060005b600185015461ffff16821015610a51576000818152600286016020526040812054905b6008811015610a3c57836107a181611c72565b600189015490955061ffff1685119050610a3c57600581901b82901b6001600160e01b0319811660009081526020899052604081205460601c90805b888110156108fa57826001600160a01b03168c828151811061080157610801611c8b565b6020026020010151600001516001600160a01b0316036108e857838c828151811061082e5761082e611c8b565b6020026020010151602001518b838151811061084c5761084c611c8b565b602002602001015160ff168151811061086757610867611c8b565b60200260200101906001600160e01b03191690816001600160e01b0319168152505060ff8a828151811061089d5761089d611c8b565b602002602001015160ff16106108b257600080fd5b8981815181106108c4576108c4611c8b565b6020026020010180518091906108d990611ca1565b60ff16905250600191506108fa565b806108f281611c72565b9150506107dd565b50801561090957505050610a2a565b818b898151811061091c5761091c611c8b565b60209081029190910101516001600160a01b03909116905260018a015461ffff1667ffffffffffffffff81111561095557610955611a94565b60405190808252806020026020018201604052801561097e578160200160208202803683370190505b508b898151811061099157610991611c8b565b602002602001015160200181905250828b89815181106109b3576109b3611c8b565b6020026020010151602001516000815181106109d1576109d1611c8b565b60200260200101906001600160e01b03191690816001600160e01b031916815250506001898981518110610a0757610a07611c8b565b60ff9092166020928302919091019091015287610a2381611c72565b9850505050505b80610a3481611c72565b91505061078e565b50508080610a4990611c72565b91505061076b565b5060005b82811015610ab8576000848281518110610a7157610a71611c8b565b602002602001015160ff1690506000878381518110610a9257610a92611c8b565b602002602001015160200151905081815250508080610ab090611c72565b915050610a55565b508185525050505090565b60006103016110dc565b6000610301610ec9565b610adf610ec9565b6001600160a01b0316336001600160a01b031614610b1057604051632f7a8ee160e01b815260040160405180910390fd5b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9680546001600160a01b0319166001600160a01b03831617905550565b50565b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc94546060907f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc939061ffff1667ffffffffffffffff811115610bb357610bb3611a94565b604051908082528060200260200182016040528015610bdc578160200160208202803683370190505b50915060008060005b600184015461ffff16821015610cc5576000818152600285016020526040812054905b6008811015610cb05783610c1b81611c72565b600188015490955061ffff1685119050610cb057600581901b82901b6001600160e01b0319811660009081526020889052604090205460601c6001600160a01b038a1603610c9d5780888781518110610c7657610c76611c8b565b6001600160e01b03199092166020928302919091019091015285610c9981611c72565b9650505b5080610ca881611c72565b915050610c08565b50508080610cbd90611c72565b915050610be5565b5050825250919050565b610cd7610ec9565b6001600160a01b0316336001600160a01b031614610d0857604051632f7a8ee160e01b815260040160405180910390fd5b610b4d8161113e565b7ff298352fd56f58214bf2245c2b202523f72fca3199077ce992640958228b281f90565b7f7e2d07d64a14e19cbb404a97c70a37424fe26c0b914348bf23e7cf52a012c2eb90565b7f99574a7094154bb123ae6ae102096f0bf9679b85a5cd1e727aaa0ae5f132e6b190565b7f5c326f5dbb0f8295b6973e9519c6a49d522fd1c150da562fee87f19638cabf3090565b80546001019055565b7ffc606c433378e3a7e0a6a531deac289b66caa1b4aa8554fd4ab2c6f1570f92d890565b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9390565b7f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046090565b7fd3889cc5458b268d0544e5534672df1296288ca3f93cbd39bd6f497a5c62281190565b6000610e4f836001600160a01b038416611181565b9392505050565b600080356001600160e01b03191681527f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc93602052604090205460601c80610ec657507f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc96546001600160a01b031690565b90565b60007f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f6716804605b546001600160a01b0316919050565b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc94547f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc939061ffff811690819060009060071615610f6b5750600381901c60009081526002840160205260409020545b60005b8751811015611050576000888281518110610f8b57610f8b611c8b565b60200260200101519050600081602001519050816040015151600003610fc45760405163eb6c3aeb60e01b815260040160405180910390fd5b6000816002811115610fd857610fd8611cc0565b03610ff357610fe9878686856111c4565b9095509350611046565b600181600281111561100757611007611cc0565b0361101b576110168783611308565b611046565b600281600281111561102f5761102f611cc0565b036110465761104087868685611458565b90955093505b5050600101610f6e565b5082821461106c5760018401805461ffff191661ffff84161790555b600782161561108e57600382901c600090815260028501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516110c193929190611d26565b60405180910390a16110d38686611680565b50505050505050565b60007f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce6617890610eed565b61110d33611764565b7f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce661789080546001600160a01b0319169055565b7f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce661789080546001600160a01b0319166001600160a01b038316179055610b4d81818181565b6000818152600183016020526040812054610349575081546001808201845560008481526020808220909301849055845493815293810190915260409092205590565b805160009081906001600160a01b031630148015906111ec575082516001600160a01b03163b155b1561120a57604051633ddc5cab60e21b815260040160405180910390fd5b60005b8360400151518110156112fb5760008460400151828151811061123257611232611c8b565b6020908102919091018101516001600160e01b031981166000908152918a9052604090912054909150606081901c1561127e57604051634923a77160e11b815260040160405180910390fd5b85516001600160e01b0319838116600081815260208d90526040902060609390931b6bffffffffffffffffffffffff19168b1790925560058a901b60e090811692831c91831c199990991617978190036112ec57600389901c600090815260028b0160205260408120989098555b5050506001958601950161120d565b5093959294509192505050565b80516001600160a01b03163b61133157604051633ddc5cab60e21b815260040160405180910390fd5b60005b8160400151518110156114535760008260400151828151811061135957611359611c8b565b6020908102919091018101516001600160e01b03198116600090815291869052604090912054909150606081901c806113a5576040516337e25a9760e11b815260040160405180910390fd5b306001600160a01b038216036113ce5760405163e983573160e01b815260040160405180910390fd5b84600001516001600160a01b0316816001600160a01b031603611404576040516330baabf360e11b815260040160405180910390fd5b5083516001600160e01b031992909216600090815260208690526040902060609290921b6bffffffffffffffffffffffff19166bffffffffffffffffffffffff91909116179055600101611334565b505050565b805160009081906001600160a01b03161561148657604051633ab3490960e21b815260040160405180910390fd5b600385901c6007861660005b85604001515181101561166c576000866040015182815181106114b7576114b7611c8b565b6020908102919091018101516001600160e01b031981166000908152918c9052604090912054909150606081901c611502576040516337e25a9760e11b815260040160405180910390fd5b30606082901c036115265760405163e983573160e01b815260040160405180910390fd5b600089900361155257600019909401600081815260028c0160205260409020549850936007935061155a565b600019909301925b600584901b89901b6000806001600160e01b0319808416908616146115b6576001600160e01b03198316600090815260208f90526040902080546bffffffffffffffffffffffff19166bffffffffffffffffffffffff86161790555b50506001600160e01b03198316600090815260208d90526040812055611fff600383901c1660e0600584901b1687821461161957600082815260028f016020526040902080546001600160e01b031980841c19909116908516831c17905561163d565b80836001600160e01b031916901c816001600160e01b031960001b901c198d16179b505b8660000361165b57600088815260028f01602052604081208190559b505b505060019093019250611492915050565b5060039190911b1796939550929350505050565b8051156001600160a01b03831615146116ac576040516326df4ccd60e01b815260040160405180910390fd5b6001600160a01b03821615611760576001600160a01b03821630146116f3576001600160a01b0382163b6116f357604051633ddc5cab60e21b815260040160405180910390fd5b6000826001600160a01b03168260405161170d9190611def565b600060405180830381855af49150503d8060008114611748576040519150601f19603f3d011682016040523d82523d6000602084013e61174d565b606091505b5050905080611453573d6000803e3d6000fd5b5050565b7f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046080546040516001600160a01b038481169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a380546001600160a01b0319166001600160a01b0392909216919091179055565b80356001600160e01b0319811681146117f657600080fd5b919050565b60006020828403121561180d57600080fd5b610e4f826117de565b80356001600160a01b03811681146117f657600080fd5b60008083601f84011261183f57600080fd5b50813567ffffffffffffffff81111561185757600080fd5b60208301915083602082850101111561186f57600080fd5b9250929050565b60008060008060006060868803121561188e57600080fd5b853567ffffffffffffffff808211156118a657600080fd5b818801915088601f8301126118ba57600080fd5b8135818111156118c957600080fd5b8960208260051b85010111156118de57600080fd5b602083019750809650506118f460208901611816565b9450604088013591508082111561190a57600080fd5b506119178882890161182d565b969995985093965092949392505050565b6020808252825182820181905260009190848201906040850190845b818110156119695783516001600160a01b031683529284019291840191600101611944565b50909695505050505050565b600081518084526020808501945080840160005b838110156119af5781516001600160e01b03191687529582019590820190600101611989565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b83811015611a2957888303603f19018552815180516001600160a01b03168452870151878401879052611a1687850182611975565b95880195935050908601906001016119e1565b509098975050505050505050565b600060208284031215611a4957600080fd5b610e4f82611816565b6020808252825182820181905260009190848201906040850190845b818110156119695783516001600160e01b03191683529284019291840191600101611a6e565b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715611acd57611acd611a94565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715611afc57611afc611a94565b604052919050565b600067ffffffffffffffff821115611b1e57611b1e611a94565b5060051b60200190565b6000611b3b611b3684611b04565b611ad3565b83815260208082019190600586811b860136811115611b5957600080fd5b865b81811015611c4f57803567ffffffffffffffff80821115611b7c5760008081fd5b818a01915060608236031215611b925760008081fd5b611b9a611aaa565b611ba383611816565b81528683013560038110611bb75760008081fd5b8188015260408381013583811115611bcf5760008081fd5b939093019236601f850112611be657600092508283fd5b83359250611bf6611b3684611b04565b83815292871b84018801928881019036851115611c135760008081fd5b948901945b84861015611c3857611c29866117de565b82529489019490890190611c18565b918301919091525088525050948301948301611b5b565b5092979650505050505050565b634e487b7160e01b600052601160045260246000fd5b600060018201611c8457611c84611c5c565b5060010190565b634e487b7160e01b600052603260045260246000fd5b600060ff821660ff8103611cb757611cb7611c5c565b60010192915050565b634e487b7160e01b600052602160045260246000fd5b60005b83811015611cf1578181015183820152602001611cd9565b50506000910152565b60008151808452611d12816020860160208601611cd6565b601f01601f19169290920160200192915050565b6000606080830181845280875180835260808601915060808160051b87010192506020808a016000805b84811015611dbf57898703607f19018652825180516001600160a01b031688528481015160038110611d9057634e487b7160e01b84526021600452602484fd5b88860152604090810151908801899052611dac89890182611975565b9750509483019491830191600101611d50565b5050506001600160a01b0389169087015250508381036040850152611de48186611cfa565b979650505050505050565b60008251611e01818460208701611cd6565b919091019291505056fea164736f6c6343000812000a

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

000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000074b6565706572730000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064b45455045520000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003068747470733a2f2f6b6565706572732d746f6b656e2d6d657461646174612e73332e616d617a6f6e6177732e636f6d2f00000000000000000000000000000000

-----Decoded View---------------
Arg [0] : name_ (string): Keepers
Arg [1] : symbol_ (string): KEEPER
Arg [2] : baseURI_ (string): https://keepers-token-metadata.s3.amazonaws.com/

-----Encoded View---------------
10 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000060
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [2] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000007
Arg [4] : 4b65657065727300000000000000000000000000000000000000000000000000
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [6] : 4b45455045520000000000000000000000000000000000000000000000000000
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000030
Arg [8] : 68747470733a2f2f6b6565706572732d746f6b656e2d6d657461646174612e73
Arg [9] : 332e616d617a6f6e6177732e636f6d2f00000000000000000000000000000000


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  ]
[ 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.