ETH Price: $3,113.03 (+1.22%)
Gas: 3 Gwei

Token

Slice Genesis (SLG)
 

Overview

Max Total Supply

35 SLG

Holders

17

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 SLG
0xff0C998D921394D89c5649712422622E3172480C
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
SliceGenesis

Compiler Version
v0.8.13+commit.abaa5c0e

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 24 : SliceGenesis.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./extensions/Purchasable/SlicerPurchasable.sol";
import "@rari-capital/solmate/src/tokens/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
import "@openzeppelin/contracts/interfaces/IERC20.sol";
import "./utils/sliceV1/interfaces/IProductsModule.sol";
import "./utils/sliceV1/interfaces/ISliceCore.sol";

/**
 * @title SliceGenesis
 * @author jjranalli
 *
 * @notice ERC721 Implementation that uses SlicerPurchasable extension to handle NFT drop for Slice V1 launch.
 *
 * - Relies on allowlist mechanic for all products except product #4
 * - product #4 is based on quantity of SLX token owned
 *
 * Won't be possible to create new allowlists once contract ownership is renounced.
 */
contract SliceGenesis is ERC721, SlicerPurchasable, Ownable {
    /// ============ Errors ============

    // Thrown when an invalid query is made
    error Invalid();
    // Thrown when max supply set is reached
    error MaxSupply();

    /// ============ Libaries ============

    using Counters for Counters.Counter;
    using Strings for uint256;

    /// ============ Storage ============

    // Token ID counter
    Counters.Counter private _tokenIds;
    // Addresses for initial mint
    address[] private ADDRESSES_TO_MINT = [
        0xff0C998D921394D89c5649712422622E3172480C,
        0xc2cA7A683Db047D221F5F8cF2de34361a399a6d5,
        0xA6FB48C1ab0CB9Ef3015D920fBb15860427008c5,
        0x5d95baEBB8412AD827287240A5c281E3bB30d27E,
        0x5C8e99481e9D02F9efDF45FF73268D7123D2817D,
        0x26FDc242eCCc144971e558FF458a4ec21B75D4E8,
        0x26416423d530b1931A2a7a6b7D435Fac65eED27d,
        0xf0549d13B142B37F0663E6B52CE54BD312A2eDaa
    ];
    // Max token supply
    uint16 private constant MAX_SUPPLY = 4200;
    // Slicer address
    address private _slicerAddress;
    // SLX Address
    address private _slxAddress;
    // Temporary URI
    string private _tempURI;
    // Base URI
    string private _baseURI;
    // SLX
    IERC20 private immutable _slx;
    // Mapping from productIds to Merkle roots
    mapping(uint256 => bytes32) _merkleRoots;

    /// ============ Constructor ============

    constructor(
        string memory name_,
        string memory symbol_,
        address slxAddress_,
        address sliceCoreAddress_,
        address productsModuleAddress_,
        uint256 slicerId_
    ) ERC721(name_, symbol_) SlicerPurchasable(productsModuleAddress_, slicerId_) {
        _slx = IERC20(slxAddress_);
        _slicerAddress = ISliceCore(sliceCoreAddress_).slicers(slicerId_);

        // Mint NFTs to those that already claimed from previous contract
        _initMint(ADDRESSES_TO_MINT);
    }

    /// ============ Functions ============

    /**
     * @notice Overridable function containing the requirements for an account to be eligible for the purchase.
     *
     * @dev Used on the Slice interface to check whether a user is able to buy a product. See {ISlicerPurchasable}.
     * @dev Max quantity purchasable per address and total mint amount is handled on Slicer product logic
     */
    function isPurchaseAllowed(
        uint256 slicerId,
        uint256 productId,
        address account,
        uint256 quantity,
        bytes memory,
        bytes memory buyerCustomData
    ) public view override returns (bool isAllowed) {
        // Check max supply is not exceeded
        if (_tokenIds.current() + quantity > MAX_SUPPLY) revert MaxSupply();

        // For all products except product #4, use allowlists
        if (productId != 4) {
            if (_merkleRoots[productId] != bytes32(0)) {
                // Get Merkle proof from buyerCustomData
                bytes32[] memory proof = abi.decode(buyerCustomData, (bytes32[]));

                // Generate leaf from account address
                bytes32 leaf = keccak256(abi.encodePacked(account));

                // Check if Merkle proof is valid
                isAllowed = MerkleProof.verify(proof, _merkleRoots[productId], leaf);
            } else {
                isAllowed = true;
            }
        } else {
            // Get purchased units
            uint256 purchasedUnits = IProductsModule(_productsModuleAddress).validatePurchaseUnits(
                account,
                slicerId,
                uint32(productId)
            );

            // Calculate total quantity purchased
            /// @dev Quantity is included in purchased units during purchase
            uint256 totalQuantity = msg.sender == _productsModuleAddress
                ? purchasedUnits
                : quantity + purchasedUnits;

            // Check if accounts holds at least (25k * totalQuantity) SLX
            isAllowed = _slx.balanceOf(account) >= totalQuantity * 25 * 10**21;
        }
    }

    function onProductPurchase(
        uint256 slicerId,
        uint256 productId,
        address account,
        uint256 quantity,
        bytes memory slicerCustomData,
        bytes memory buyerCustomData
    ) external payable override onlyOnPurchaseFrom(slicerId) {
        // Check whether the account is allowed to buy a product.
        if (
            !isPurchaseAllowed(
                slicerId,
                productId,
                account,
                quantity,
                slicerCustomData,
                buyerCustomData
            )
        ) revert NotAllowed();

        // Mint number of NFTs equal to purchased quantity
        for (uint256 i = 0; i < quantity; ) {
            _mint(account);

            unchecked {
                ++i;
            }
        }
    }

    /**
     * Returns URI of tokenId
     */
    function tokenURI(uint256 tokenId) public view override returns (string memory) {
        if (tokenId > _tokenIds.current()) revert Invalid();

        return
            bytes(_baseURI).length > 0
                ? string(abi.encodePacked(_baseURI, tokenId.toString()))
                : _tempURI;
    }

    function totalSupply() external view returns (uint256) {
        return _tokenIds.current();
    }

    /**
     * @dev See {IERC165-royaltyInfo}.
     */
    function royaltyInfo(uint256, uint256 salePrice) external view returns (address, uint256) {
        return (_slicerAddress, salePrice / 10);
    }

    /**
     * Sets _baseURI
     *
     * @dev Only accessible to contract owner
     */
    function _setBaseURI(string memory baseURI_) external onlyOwner {
        _baseURI = baseURI_;
    }

    /**
     * Sets _tempURI
     *
     * @dev Only accessible to contract owner
     */
    function _setTempURI(string memory tempURI_) external onlyOwner {
        _tempURI = tempURI_;
    }

    /**
     * Sets merkleRoot for productId
     *
     * @dev Only accessible to contract owner
     */
    function _setMerkleRoot(uint256 productId, bytes32 merkleRoot) external onlyOwner {
        _merkleRoots[productId] = merkleRoot;
    }

    /**
     * Mints 1 NFT and increases tokenId
     */
    function _mint(address to) private {
        _tokenIds.increment();
        _safeMint(to, _tokenIds.current());
    }

    /**
     * Mints nfts to those who already claimed the previous collection from the allowlist
     *
     * @dev Only called during constructor
     */
    function _initMint(address[] memory addresses) private {
        for (uint256 i = 0; i < addresses.length; ) {
            _mint(addresses[i]);

            unchecked {
                ++i;
            }
        }
    }
}

File 2 of 24 : SlicerPurchasable.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity ^0.8.0;

import "../../interfaces/extensions/Purchasable/ISlicerPurchasable.sol";

/**
 * @title SlicerPurchasable
 * @author jjranalli
 *
 * @notice Extension enabling basic usage of external calls by slicers upon product purchase.
 */
abstract contract SlicerPurchasable is ISlicerPurchasable {
    /// ============ Errors ============

    /// @notice Thrown if not called from the correct slicer
    error WrongSlicer();
    /// @notice Thrown if not called during product purchase
    error NotPurchase();
    /// @notice Thrown when account is not allowed to buy product
    error NotAllowed();
    /// @notice Thrown when a critical request was not successful
    error NotSuccessful();

    /// ============ Storage ============

    /// ProductsModule contract address
    address internal _productsModuleAddress;
    /// Id of the slicer able to call the functions with the `OnlyOnPurchaseFrom` function
    uint256 internal immutable _slicerId;

    /// ============ Constructor ============

    /**
     * @notice Initializes the contract.
     *
     * @param productsModuleAddress_ {ProductsModule} address
     * @param slicerId_ ID of the slicer linked to this contract
     */
    constructor(address productsModuleAddress_, uint256 slicerId_) {
        _productsModuleAddress = productsModuleAddress_;
        _slicerId = slicerId_;
    }

    /// ============ Modifiers ============

    /**
     * @notice Checks product purchases are accepted only from correct slicer (modifier)
     */
    modifier onlyOnPurchaseFrom(uint256 slicerId) {
        _onlyOnPurchaseFrom(slicerId);
        _;
    }

    /// ============ Functions ============

    /**
     * @notice Checks product purchases are accepted only from correct slicer (function)
     */
    function _onlyOnPurchaseFrom(uint256 slicerId) internal view virtual {
        if (_slicerId != slicerId) revert WrongSlicer();
        if (msg.sender != _productsModuleAddress) revert NotPurchase();
    }

    /**
     * @notice Overridable function containing the requirements for an account to be eligible for the purchase.
     *
     * @dev Used on the Slice interface to check whether a user is able to buy a product. See {ISlicerPurchasable}.
     */
    function isPurchaseAllowed(
        uint256,
        uint256,
        address,
        uint256,
        bytes memory,
        bytes memory
    ) public view virtual override returns (bool) {
        // Add all requirements related to product purchase here
        // Return true if account is allowed to buy product
        return true;
    }

    /**
     * @notice Overridable function to handle external calls on product purchases from slicers. See {ISlicerPurchasable}
     *
     * @dev Can be inherited by child contracts to add custom logic on product purchases.
     */
    function onProductPurchase(
        uint256 slicerId,
        uint256 productId,
        address account,
        uint256 quantity,
        bytes memory slicerCustomData,
        bytes memory buyerCustomData
    ) external payable virtual override onlyOnPurchaseFrom(slicerId) {
        // Check whether the account is allowed to buy a product.
        if (
            !isPurchaseAllowed(
                slicerId,
                productId,
                account,
                quantity,
                slicerCustomData,
                buyerCustomData
            )
        ) revert NotAllowed();

        // Add product purchase logic here
    }
}

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

/// @notice Modern, minimalist, and gas efficient ERC-721 implementation.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)
/// @dev Note that balanceOf does not revert if passed the zero address, in defiance of the ERC.
abstract contract ERC721 {
    /*///////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event Transfer(address indexed from, address indexed to, uint256 indexed id);

    event Approval(address indexed owner, address indexed spender, uint256 indexed id);

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

    /*///////////////////////////////////////////////////////////////
                          METADATA STORAGE/LOGIC
    //////////////////////////////////////////////////////////////*/

    string public name;

    string public symbol;

    function tokenURI(uint256 id) public view virtual returns (string memory);

    /*///////////////////////////////////////////////////////////////
                            ERC721 STORAGE                        
    //////////////////////////////////////////////////////////////*/

    mapping(address => uint256) public balanceOf;

    mapping(uint256 => address) public ownerOf;

    mapping(uint256 => address) public getApproved;

    mapping(address => mapping(address => bool)) public isApprovedForAll;

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

    constructor(string memory _name, string memory _symbol) {
        name = _name;
        symbol = _symbol;
    }

    /*///////////////////////////////////////////////////////////////
                              ERC721 LOGIC
    //////////////////////////////////////////////////////////////*/

    function approve(address spender, uint256 id) public virtual {
        address owner = ownerOf[id];

        require(msg.sender == owner || isApprovedForAll[owner][msg.sender], "NOT_AUTHORIZED");

        getApproved[id] = spender;

        emit Approval(owner, spender, id);
    }

    function setApprovalForAll(address operator, bool approved) public virtual {
        isApprovedForAll[msg.sender][operator] = approved;

        emit ApprovalForAll(msg.sender, operator, approved);
    }

    function transferFrom(
        address from,
        address to,
        uint256 id
    ) public virtual {
        require(from == ownerOf[id], "WRONG_FROM");

        require(to != address(0), "INVALID_RECIPIENT");

        require(
            msg.sender == from || msg.sender == getApproved[id] || isApprovedForAll[from][msg.sender],
            "NOT_AUTHORIZED"
        );

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        unchecked {
            balanceOf[from]--;

            balanceOf[to]++;
        }

        ownerOf[id] = to;

        delete getApproved[id];

        emit Transfer(from, to, id);
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 id
    ) public virtual {
        transferFrom(from, to, id);

        require(
            to.code.length == 0 ||
                ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, "") ==
                ERC721TokenReceiver.onERC721Received.selector,
            "UNSAFE_RECIPIENT"
        );
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        bytes memory data
    ) public virtual {
        transferFrom(from, to, id);

        require(
            to.code.length == 0 ||
                ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==
                ERC721TokenReceiver.onERC721Received.selector,
            "UNSAFE_RECIPIENT"
        );
    }

    /*///////////////////////////////////////////////////////////////
                              ERC165 LOGIC
    //////////////////////////////////////////////////////////////*/

    function supportsInterface(bytes4 interfaceId) public pure virtual returns (bool) {
        return
            interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165
            interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721
            interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata
    }

    /*///////////////////////////////////////////////////////////////
                       INTERNAL MINT/BURN LOGIC
    //////////////////////////////////////////////////////////////*/

    function _mint(address to, uint256 id) internal virtual {
        require(to != address(0), "INVALID_RECIPIENT");

        require(ownerOf[id] == address(0), "ALREADY_MINTED");

        // Counter overflow is incredibly unrealistic.
        unchecked {
            balanceOf[to]++;
        }

        ownerOf[id] = to;

        emit Transfer(address(0), to, id);
    }

    function _burn(uint256 id) internal virtual {
        address owner = ownerOf[id];

        require(ownerOf[id] != address(0), "NOT_MINTED");

        // Ownership check above ensures no underflow.
        unchecked {
            balanceOf[owner]--;
        }

        delete ownerOf[id];

        delete getApproved[id];

        emit Transfer(owner, address(0), id);
    }

    /*///////////////////////////////////////////////////////////////
                       INTERNAL SAFE MINT LOGIC
    //////////////////////////////////////////////////////////////*/

    function _safeMint(address to, uint256 id) internal virtual {
        _mint(to, id);

        require(
            to.code.length == 0 ||
                ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, "") ==
                ERC721TokenReceiver.onERC721Received.selector,
            "UNSAFE_RECIPIENT"
        );
    }

    function _safeMint(
        address to,
        uint256 id,
        bytes memory data
    ) internal virtual {
        _mint(to, id);

        require(
            to.code.length == 0 ||
                ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) ==
                ERC721TokenReceiver.onERC721Received.selector,
            "UNSAFE_RECIPIENT"
        );
    }
}

/// @notice A generic interface for a contract which properly accepts ERC721 tokens.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)
interface ERC721TokenReceiver {
    function onERC721Received(
        address operator,
        address from,
        uint256 id,
        bytes calldata data
    ) external returns (bytes4);
}

File 4 of 24 : 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 5 of 24 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 6 of 24 : MerkleProof.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/cryptography/MerkleProof.sol)

pragma solidity ^0.8.0;

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

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merklee tree up
     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
     * hash matches the root of the tree. When processing the proof, the pairs
     * of leafs & pre-images are assumed to be sorted.
     *
     * _Available since v4.4._
     */
    function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            bytes32 proofElement = proof[i];
            if (computedHash <= proofElement) {
                // Hash(current computed hash + current element of the proof)
                computedHash = _efficientHash(computedHash, proofElement);
            } else {
                // Hash(current element of the proof + current computed hash)
                computedHash = _efficientHash(proofElement, computedHash);
            }
        }
        return computedHash;
    }

    function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}

File 7 of 24 : Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

File 8 of 24 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol)

pragma solidity ^0.8.0;

import "../token/ERC20/IERC20.sol";

File 9 of 24 : IProductsModule.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

import "../structs/Function.sol";
import "../structs/ProductParams.sol";
import "../structs/PurchaseParams.sol";

interface IProductsModule {
    function addProduct(
        uint256 slicerId,
        ProductParams memory params,
        Function memory externalCall_
    ) external;

    function setProductInfo(
        uint256 slicerId,
        uint32 productId,
        uint8 newMaxUnits,
        bool isFree,
        bool isInfinite,
        uint32 newUnits,
        CurrencyPrice[] memory currencyPrices
    ) external;

    function removeProduct(uint256 slicerId, uint32 productId) external;

    function payProducts(address buyer, PurchaseParams[] calldata purchases) external payable;

    function releaseEthToSlicer(uint256 slicerId) external;

    // function _setCategoryAddress(uint256 categoryIndex, address newCategoryAddress) external;

    function ethBalance(uint256 slicerId) external view returns (uint256);

    function productPrice(
        uint256 slicerId,
        uint32 productId,
        address currency
    ) external view returns (uint256 ethPayment, uint256 currencyPayment);

    function validatePurchaseUnits(
        address account,
        uint256 slicerId,
        uint32 productId
    ) external view returns (uint256 purchases);

    function validatePurchase(uint256 slicerId, uint32 productId)
        external
        view
        returns (uint256 purchases, bytes memory purchaseData);

    // function categoryAddress(uint256 categoryIndex) external view returns (address);
}

File 10 of 24 : ISliceCore.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

import "../structs/Payee.sol";

import "./utils/IOwnable.sol";
import "@openzeppelin/contracts-upgradeable/interfaces/IERC1155Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol";

interface ISliceCore is IOwnable, IERC1155Upgradeable, IERC2981Upgradeable {
    function slice(
        Payee[] calldata payees,
        uint256 minimumShares,
        address[] calldata currencies,
        uint256 releaseTimelock,
        uint40 transferableTimelock,
        bool isImmutable,
        bool isControlled
    ) external;

    function reslice(
        uint256 tokenId,
        address payable[] calldata accounts,
        int32[] calldata tokensDiffs
    ) external;

    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) external override;

    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) external override;

    function slicerBatchTransfer(
        address from,
        address[] memory recipients,
        uint256 id,
        uint256[] memory amounts,
        bool release
    ) external;

    function safeTransferFromUnreleased(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) external;

    function setController(uint256 id, address newController) external;

    function setRoyalty(
        uint256 tokenId,
        bool isSlicer,
        bool isActive,
        uint256 royaltyPercentage
    ) external;

    function royaltyInfo(uint256 tokenId, uint256 salePrice)
        external
        view
        override
        returns (address receiver, uint256 royaltyAmount);

    function slicers(uint256 id) external view returns (address);

    function controller(uint256 id) external view returns (address);

    function totalSupply(uint256 id) external view returns (uint256);

    function supply() external view returns (uint256);

    function exists(uint256 id) external view returns (bool);

    function _setBasePath(string calldata basePath_) external;

    function _togglePause() external;
}

File 11 of 24 : ISlicerPurchasable.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity ^0.8.0;

interface ISlicerPurchasable {
    /**
     * @notice Overridable function containing the requirements for an account to be eligible for the purchase.
     *
     * @param slicerId ID of the slicer calling the function
     * @param productId ID of the product being purchased
     * @param account Address of the account buying the product
     * @param quantity Amount of products being purchased
     * @param slicerCustomData Custom data sent by slicer during product purchase
     * @param buyerCustomData Custom data sent by buyer during product purchase
     *
     * @dev Used on the Slice interface to check whether a user is able to buy a product.
     */
    function isPurchaseAllowed(
        uint256 slicerId,
        uint256 productId,
        address account,
        uint256 quantity,
        bytes memory slicerCustomData,
        bytes memory buyerCustomData
    ) external view returns (bool);

    /**
     * @notice Overridable function to handle external calls on product purchases from slicers.
     *
     * @param slicerId ID of the slicer calling the function
     * @param productId ID of the product being purchased
     * @param account Address of the account buying the product
     * @param quantity Amount of products being purchased
     * @param slicerCustomData Custom data sent by slicer during product purchase
     * @param buyerCustomData Custom data sent by buyer during product purchase
     *
     * @dev Can be inherited by child contracts to add custom logic on product purchases.
     */
    function onProductPurchase(
        uint256 slicerId,
        uint256 productId,
        address account,
        uint256 quantity,
        bytes memory slicerCustomData,
        bytes memory buyerCustomData
    ) external payable;
}

File 12 of 24 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

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

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

File 13 of 24 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

File 14 of 24 : Function.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

struct Function {
    bytes data;
    uint256 value;
    address externalAddress;
    bytes4 checkFunctionSignature;
    bytes4 execFunctionSignature;
}

File 15 of 24 : ProductParams.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./SubSlicerProduct.sol";
import "./CurrencyPrice.sol";

struct ProductParams {
    SubSlicerProduct[] subSlicerProducts;
    CurrencyPrice[] currencyPrices;
    bytes data;
    bytes purchaseData;
    uint32 availableUnits;
    // uint32 categoryIndex;
    uint8 maxUnitsPerBuyer;
    bool isFree;
    bool isInfinite;
}

File 16 of 24 : PurchaseParams.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

struct PurchaseParams {
    uint128 slicerId;
    uint32 quantity;
    address currency;
    uint32 productId;
    bytes buyerCustomData;
}

File 17 of 24 : SubSlicerProduct.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

struct SubSlicerProduct {
    uint128 subSlicerId;
    uint32 subProductId;
}

File 18 of 24 : CurrencyPrice.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

struct CurrencyPrice {
    uint248 value;
    bool dynamicPricing;
    address currency;
}

File 19 of 24 : Payee.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

struct Payee {
    address account;
    uint32 shares;
}

File 20 of 24 : IOwnable.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

interface IOwnable {
    function owner() external view returns (address);

    function transferOwnership(address newOwner) external;

    function renounceOwnership() external;
}

File 21 of 24 : IERC1155Upgradeable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1155.sol)

pragma solidity ^0.8.0;

import "../token/ERC1155/IERC1155Upgradeable.sol";

File 22 of 24 : IERC2981Upgradeable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/IERC2981.sol)

pragma solidity ^0.8.0;

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

/**
 * @dev Interface for the NFT Royalty Standard.
 *
 * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal
 * support for royalty payments across all NFT marketplaces and ecosystem participants.
 *
 * _Available since v4.5._
 */
interface IERC2981Upgradeable is IERC165Upgradeable {
    /**
     * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of
     * exchange. The royalty amount is denominated and should be payed in that same unit of exchange.
     */
    function royaltyInfo(uint256 tokenId, uint256 salePrice)
        external
        view
        returns (address receiver, uint256 royaltyAmount);
}

File 23 of 24 : IERC1155Upgradeable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/IERC1155.sol)

pragma solidity ^0.8.0;

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

/**
 * @dev Required interface of an ERC1155 compliant contract, as defined in the
 * https://eips.ethereum.org/EIPS/eip-1155[EIP].
 *
 * _Available since v3.1._
 */
interface IERC1155Upgradeable is IERC165Upgradeable {
    /**
     * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
     */
    event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);

    /**
     * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
     * transfers.
     */
    event TransferBatch(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256[] ids,
        uint256[] values
    );

    /**
     * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
     * `approved`.
     */
    event ApprovalForAll(address indexed account, address indexed operator, bool approved);

    /**
     * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
     *
     * If an {URI} event was emitted for `id`, the standard
     * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
     * returned by {IERC1155MetadataURI-uri}.
     */
    event URI(string value, uint256 indexed id);

    /**
     * @dev Returns the amount of tokens of token type `id` owned by `account`.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) external view returns (uint256);

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
        external
        view
        returns (uint256[] memory);

    /**
     * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
     *
     * Emits an {ApprovalForAll} event.
     *
     * Requirements:
     *
     * - `operator` cannot be the caller.
     */
    function setApprovalForAll(address operator, bool approved) external;

    /**
     * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
     *
     * See {setApprovalForAll}.
     */
    function isApprovedForAll(address account, address operator) external view returns (bool);

    /**
     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.
     * - `from` must have a balance of tokens of type `id` of at least `amount`.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes calldata data
    ) external;

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata amounts,
        bytes calldata data
    ) external;
}

File 24 of 24 : IERC165Upgradeable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

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

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"address","name":"slxAddress_","type":"address"},{"internalType":"address","name":"sliceCoreAddress_","type":"address"},{"internalType":"address","name":"productsModuleAddress_","type":"address"},{"internalType":"uint256","name":"slicerId_","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"Invalid","type":"error"},{"inputs":[],"name":"MaxSupply","type":"error"},{"inputs":[],"name":"NotAllowed","type":"error"},{"inputs":[],"name":"NotPurchase","type":"error"},{"inputs":[],"name":"NotSuccessful","type":"error"},{"inputs":[],"name":"WrongSlicer","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"string","name":"baseURI_","type":"string"}],"name":"_setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"productId","type":"uint256"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"}],"name":"_setMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"tempURI_","type":"string"}],"name":"_setTempURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"slicerId","type":"uint256"},{"internalType":"uint256","name":"productId","type":"uint256"},{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"bytes","name":"buyerCustomData","type":"bytes"}],"name":"isPurchaseAllowed","outputs":[{"internalType":"bool","name":"isAllowed","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"slicerId","type":"uint256"},{"internalType":"uint256","name":"productId","type":"uint256"},{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"bytes","name":"slicerCustomData","type":"bytes"},{"internalType":"bytes","name":"buyerCustomData","type":"bytes"}],"name":"onProductPurchase","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6101c060405273ff0c998d921394d89c5649712422622e3172480c60c090815273c2ca7a683db047d221f5f8cf2de34361a399a6d560e05273a6fb48c1ab0cb9ef3015d920fbb15860427008c561010052735d95baebb8412ad827287240a5c281e3bb30d27e61012052735c8e99481e9d02f9efdf45ff73268d7123d2817d610140527326fdc242eccc144971e558ff458a4ec21b75d4e8610160527326416423d530b1931a2a7a6b7d435fac65eed27d6101805273f0549d13b142b37f0663e6b52ce54bd312a2edaa6101a052620000dd90600990600862000572565b50348015620000eb57600080fd5b50604051620024b8380380620024b88339810160408190526200010e916200075a565b8181878781600090805190602001906200012a929190620005dc565b50805162000140906001906020840190620005dc565b5050600680546001600160a01b0319166001600160a01b0394909416939093179092556080525062000179620001733390565b62000286565b6001600160a01b0384811660a052604051630bafd3f560e11b8152600481018390529084169063175fa7ea90602401602060405180830381865afa158015620001c6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ec919062000804565b600a60006101000a8154816001600160a01b0302191690836001600160a01b031602179055506200027a60098054806020026020016040519081016040528092919081815260200182805480156200026e57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116200024f575b5050620002d892505050565b505050505050620008a7565b600780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60005b81518110156200031b5762000312828281518110620002fe57620002fe62000829565b60200260200101516200031f60201b60201c565b600101620002db565b5050565b6200033660086200035b60201b62000fa11760201c565b62000358816200035260086200036460201b62000faa1760201c565b62000368565b50565b80546001019055565b5490565b62000374828262000463565b6001600160a01b0382163b15806200041e5750604051630a85bd0160e11b80825233600483015260006024830181905260448301849052608060648401526084830152906001600160a01b0384169063150b7a029060a4016020604051808303816000875af1158015620003ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200041291906200083f565b6001600160e01b031916145b6200031b5760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b60448201526064015b60405180910390fd5b6001600160a01b038216620004af5760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b60448201526064016200045a565b6000818152600360205260409020546001600160a01b031615620005075760405162461bcd60e51b815260206004820152600e60248201526d1053149150511657d3525395115160921b60448201526064016200045a565b6001600160a01b038216600081815260026020908152604080832080546001019055848352600390915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b828054828255906000526020600020908101928215620005ca579160200282015b82811115620005ca57825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019062000593565b50620005d892915062000659565b5090565b828054620005ea906200086b565b90600052602060002090601f0160209004810192826200060e5760008555620005ca565b82601f106200062957805160ff1916838001178555620005ca565b82800160010185558215620005ca579182015b82811115620005ca5782518255916020019190600101906200063c565b5b80821115620005d857600081556001016200065a565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200069857600080fd5b81516001600160401b0380821115620006b557620006b562000670565b604051601f8301601f19908116603f01168101908282118183101715620006e057620006e062000670565b81604052838152602092508683858801011115620006fd57600080fd5b600091505b8382101562000721578582018301518183018401529082019062000702565b83821115620007335760008385830101525b9695505050505050565b80516001600160a01b03811681146200075557600080fd5b919050565b60008060008060008060c087890312156200077457600080fd5b86516001600160401b03808211156200078c57600080fd5b6200079a8a838b0162000686565b97506020890151915080821115620007b157600080fd5b50620007c089828a0162000686565b955050620007d1604088016200073d565b9350620007e1606088016200073d565b9250620007f1608088016200073d565b915060a087015190509295509295509295565b6000602082840312156200081757600080fd5b62000822826200073d565b9392505050565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156200085257600080fd5b81516001600160e01b0319811681146200082257600080fd5b600181811c908216806200088057607f821691505b602082108103620008a157634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a051611beb620008cd6000396000610b86015260006110190152611beb6000f3fe6080604052600436106101405760003560e01c8063715018a6116100b6578063a23fffb91161006f578063a23fffb9146103d9578063b88d4fde146103ec578063c87b56dd1461040c578063e985e9c51461042c578063ea0875ea14610467578063f2fde38b1461048757600080fd5b8063715018a6146103315780638da5cb5b1461034657806395d89b411461036457806395db9368146103795780639954343814610399578063a22cb465146103b957600080fd5b806323b872dd1161010857806323b872dd1461022f5780632a55205a1461024f57806331b5b9071461028e57806342842e0e146102ae5780636352211e146102ce57806370a082311461030457600080fd5b806301ffc9a71461014557806306fdde031461017a578063081812fc1461019c578063095ea7b3146101ea57806318160ddd1461020c575b600080fd5b34801561015157600080fd5b506101656101603660046114a4565b6104a7565b60405190151581526020015b60405180910390f35b34801561018657600080fd5b5061018f6104f9565b6040516101719190611520565b3480156101a857600080fd5b506101d26101b7366004611533565b6004602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610171565b3480156101f657600080fd5b5061020a610205366004611568565b610587565b005b34801561021857600080fd5b5061022161066e565b604051908152602001610171565b34801561023b57600080fd5b5061020a61024a366004611592565b61067e565b34801561025b57600080fd5b5061026f61026a3660046115ce565b610845565b604080516001600160a01b039093168352602083019190915201610171565b34801561029a57600080fd5b5061020a6102a936600461168f565b61086d565b3480156102ba57600080fd5b5061020a6102c9366004611592565b6108ae565b3480156102da57600080fd5b506101d26102e9366004611533565b6003602052600090815260409020546001600160a01b031681565b34801561031057600080fd5b5061022161031f3660046116d8565b60026020526000908152604090205481565b34801561033d57600080fd5b5061020a610983565b34801561035257600080fd5b506007546001600160a01b03166101d2565b34801561037057600080fd5b5061018f6109b9565b34801561038557600080fd5b50610165610394366004611713565b6109c6565b3480156103a557600080fd5b5061020a6103b436600461168f565b610c02565b3480156103c557600080fd5b5061020a6103d43660046117a3565b610c3f565b61020a6103e7366004611713565b610cab565b3480156103f857600080fd5b5061020a6104073660046117df565b610d06565b34801561041857600080fd5b5061018f610427366004611533565b610dc8565b34801561043857600080fd5b50610165610447366004611847565b600560209081526000928352604080842090915290825290205460ff1681565b34801561047357600080fd5b5061020a6104823660046115ce565b610eca565b34801561049357600080fd5b5061020a6104a23660046116d8565b610f06565b60006301ffc9a760e01b6001600160e01b0319831614806104d857506380ac58cd60e01b6001600160e01b03198316145b806104f35750635b5e139f60e01b6001600160e01b03198316145b92915050565b600080546105069061187a565b80601f01602080910402602001604051908101604052809291908181526020018280546105329061187a565b801561057f5780601f106105545761010080835404028352916020019161057f565b820191906000526020600020905b81548152906001019060200180831161056257829003601f168201915b505050505081565b6000818152600360205260409020546001600160a01b0316338114806105d057506001600160a01b038116600090815260056020908152604080832033845290915290205460ff165b6106125760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064015b60405180910390fd5b60008281526004602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b600061067960085490565b905090565b6000818152600360205260409020546001600160a01b038481169116146106d45760405162461bcd60e51b815260206004820152600a60248201526957524f4e475f46524f4d60b01b6044820152606401610609565b6001600160a01b03821661071e5760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610609565b336001600160a01b038416148061074b57506000818152600460205260409020546001600160a01b031633145b8061077957506001600160a01b038316600090815260056020908152604080832033845290915290205460ff165b6107b65760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b6044820152606401610609565b6001600160a01b0380841660008181526002602090815260408083208054600019019055938616808352848320805460010190558583526003825284832080546001600160a01b03199081168317909155600490925284832080549092169091559251849392917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600a805460009182916001600160a01b03169061086290856118e0565b915091509250929050565b6007546001600160a01b031633146108975760405162461bcd60e51b8152600401610609906118f4565b80516108aa90600d9060208401906113f5565b5050565b6108b983838361067e565b6001600160a01b0382163b15806109625750604051630a85bd0160e11b8082523360048301526001600160a01b03858116602484015260448301849052608060648401526000608484015290919084169063150b7a029060a4016020604051808303816000875af1158015610932573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109569190611929565b6001600160e01b031916145b61097e5760405162461bcd60e51b815260040161060990611946565b505050565b6007546001600160a01b031633146109ad5760405162461bcd60e51b8152600401610609906118f4565b6109b76000610fae565b565b600180546105069061187a565b6000611068846109d560085490565b6109df9190611970565b11156109fe57604051632cdb04a160e21b815260040160405180910390fd5b85600414610a9c576000868152600e602052604090205415610a9457600082806020019051810190610a309190611988565b6040516bffffffffffffffffffffffff19606089901b166020820152909150600090603401604051602081830303815290604052805190602001209050610a8b82600e60008b81526020019081526020016000205483611000565b92505050610bf8565b506001610bf8565b6006546040516362bb919960e11b81526001600160a01b038781166004830152602482018a905263ffffffff89166044830152600092169063c577233290606401602060405180830381865afa158015610afa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b1e9190611a2e565b6006549091506000906001600160a01b03163314610b4557610b408287611970565b610b47565b815b9050610b54816019611a47565b610b6790683635c9adc5dea00000611a47565b6040516370a0823160e01b81526001600160a01b0389811660048301527f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015610bcd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf19190611a2e565b1015925050505b9695505050505050565b6007546001600160a01b03163314610c2c5760405162461bcd60e51b8152600401610609906118f4565b80516108aa90600c9060208401906113f5565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b85610cb581611016565b610cc38787878787876109c6565b610ce057604051631eb49d6d60e11b815260040160405180910390fd5b60005b84811015610cfc57610cf486611081565b600101610ce3565b5050505050505050565b610d1184848461067e565b6001600160a01b0383163b1580610da65750604051630a85bd0160e11b808252906001600160a01b0385169063150b7a0290610d57903390899088908890600401611a66565b6020604051808303816000875af1158015610d76573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d9a9190611929565b6001600160e01b031916145b610dc25760405162461bcd60e51b815260040161060990611946565b50505050565b6060610dd360085490565b821115610df357604051636dac6a0960e01b815260040160405180910390fd5b6000600d8054610e029061187a565b905011610e9957600c8054610e169061187a565b80601f0160208091040260200160405190810160405280929190818152602001828054610e429061187a565b8015610e8f5780601f10610e6457610100808354040283529160200191610e8f565b820191906000526020600020905b815481529060010190602001808311610e7257829003601f168201915b50505050506104f3565b600d610ea4836110a1565b604051602001610eb5929190611ab5565b60405160208183030381529060405292915050565b6007546001600160a01b03163314610ef45760405162461bcd60e51b8152600401610609906118f4565b6000918252600e602052604090912055565b6007546001600160a01b03163314610f305760405162461bcd60e51b8152600401610609906118f4565b6001600160a01b038116610f955760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610609565b610f9e81610fae565b50565b80546001019055565b5490565b600780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60008261100d85846111aa565b14949350505050565b807f00000000000000000000000000000000000000000000000000000000000000001461105657604051632eafdb6960e01b815260040160405180910390fd5b6006546001600160a01b03163314610f9e576040516347322d0360e01b815260040160405180910390fd5b61108f600880546001019055565b610f9e8161109c60085490565b61121e565b6060816000036110c85750506040805180820190915260018152600360fc1b602082015290565b8160005b81156110f257806110dc81611b5b565b91506110eb9050600a836118e0565b91506110cc565b60008167ffffffffffffffff81111561110d5761110d6115f0565b6040519080825280601f01601f191660200182016040528015611137576020820181803683370190505b5090505b84156111a25761114c600183611b74565b9150611159600a86611b8b565b611164906030611970565b60f81b81838151811061117957611179611b9f565b60200101906001600160f81b031916908160001a90535061119b600a866118e0565b945061113b565b949350505050565b600081815b84518110156112165760008582815181106111cc576111cc611b9f565b602002602001015190508083116111f25760008381526020829052604090209250611203565b600081815260208490526040902092505b508061120e81611b5b565b9150506111af565b509392505050565b61122882826112ea565b6001600160a01b0382163b15806112ce5750604051630a85bd0160e11b80825233600483015260006024830181905260448301849052608060648401526084830152906001600160a01b0384169063150b7a029060a4016020604051808303816000875af115801561129e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112c29190611929565b6001600160e01b031916145b6108aa5760405162461bcd60e51b815260040161060990611946565b6001600160a01b0382166113345760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610609565b6000818152600360205260409020546001600160a01b03161561138a5760405162461bcd60e51b815260206004820152600e60248201526d1053149150511657d3525395115160921b6044820152606401610609565b6001600160a01b038216600081815260026020908152604080832080546001019055848352600390915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b8280546114019061187a565b90600052602060002090601f0160209004810192826114235760008555611469565b82601f1061143c57805160ff1916838001178555611469565b82800160010185558215611469579182015b8281111561146957825182559160200191906001019061144e565b50611475929150611479565b5090565b5b80821115611475576000815560010161147a565b6001600160e01b031981168114610f9e57600080fd5b6000602082840312156114b657600080fd5b81356114c18161148e565b9392505050565b60005b838110156114e35781810151838201526020016114cb565b83811115610dc25750506000910152565b6000815180845261150c8160208601602086016114c8565b601f01601f19169290920160200192915050565b6020815260006114c160208301846114f4565b60006020828403121561154557600080fd5b5035919050565b80356001600160a01b038116811461156357600080fd5b919050565b6000806040838503121561157b57600080fd5b6115848361154c565b946020939093013593505050565b6000806000606084860312156115a757600080fd5b6115b08461154c565b92506115be6020850161154c565b9150604084013590509250925092565b600080604083850312156115e157600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561162f5761162f6115f0565b604052919050565b600067ffffffffffffffff831115611651576116516115f0565b611664601f8401601f1916602001611606565b905082815283838301111561167857600080fd5b828260208301376000602084830101529392505050565b6000602082840312156116a157600080fd5b813567ffffffffffffffff8111156116b857600080fd5b8201601f810184136116c957600080fd5b6111a284823560208401611637565b6000602082840312156116ea57600080fd5b6114c18261154c565b600082601f83011261170457600080fd5b6114c183833560208501611637565b60008060008060008060c0878903121561172c57600080fd5b86359550602087013594506117436040880161154c565b935060608701359250608087013567ffffffffffffffff8082111561176757600080fd5b6117738a838b016116f3565b935060a089013591508082111561178957600080fd5b5061179689828a016116f3565b9150509295509295509295565b600080604083850312156117b657600080fd5b6117bf8361154c565b9150602083013580151581146117d457600080fd5b809150509250929050565b600080600080608085870312156117f557600080fd5b6117fe8561154c565b935061180c6020860161154c565b925060408501359150606085013567ffffffffffffffff81111561182f57600080fd5b61183b878288016116f3565b91505092959194509250565b6000806040838503121561185a57600080fd5b6118638361154c565b91506118716020840161154c565b90509250929050565b600181811c9082168061188e57607f821691505b6020821081036118ae57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000826118ef576118ef6118b4565b500490565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60006020828403121561193b57600080fd5b81516114c18161148e565b60208082526010908201526f155394d0519157d49150d2541251539560821b604082015260600190565b60008219821115611983576119836118ca565b500190565b6000602080838503121561199b57600080fd5b825167ffffffffffffffff808211156119b357600080fd5b818501915085601f8301126119c757600080fd5b8151818111156119d9576119d96115f0565b8060051b91506119ea848301611606565b8181529183018401918481019088841115611a0457600080fd5b938501935b83851015611a2257845182529385019390850190611a09565b98975050505050505050565b600060208284031215611a4057600080fd5b5051919050565b6000816000190483118215151615611a6157611a616118ca565b500290565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090610bf8908301846114f4565b60008151611aab8185602086016114c8565b9290920192915050565b600080845481600182811c915080831680611ad157607f831692505b60208084108203611af057634e487b7160e01b86526022600452602486fd5b818015611b045760018114611b1557611b42565b60ff19861689528489019650611b42565b60008b81526020902060005b86811015611b3a5781548b820152908501908301611b21565b505084890196505b505050505050611b528185611a99565b95945050505050565b600060018201611b6d57611b6d6118ca565b5060010190565b600082821015611b8657611b866118ca565b500390565b600082611b9a57611b9a6118b4565b500690565b634e487b7160e01b600052603260045260246000fdfea264697066735822122076ff48df4e89b9cee327b28a5c896938e051cc308853ee760ec50cd3818668c164736f6c634300080d003300000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001000000000000000000000000006fa5ff63b2752265c6bd9350591f97a7dad9e91800000000000000000000000021da1b084175f95285b49b22c018889c45e1820d000000000000000000000000689bba0e25c259b205ece8e6152ee1eacf307f5f0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000d536c6963652047656e65736973000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003534c470000000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x6080604052600436106101405760003560e01c8063715018a6116100b6578063a23fffb91161006f578063a23fffb9146103d9578063b88d4fde146103ec578063c87b56dd1461040c578063e985e9c51461042c578063ea0875ea14610467578063f2fde38b1461048757600080fd5b8063715018a6146103315780638da5cb5b1461034657806395d89b411461036457806395db9368146103795780639954343814610399578063a22cb465146103b957600080fd5b806323b872dd1161010857806323b872dd1461022f5780632a55205a1461024f57806331b5b9071461028e57806342842e0e146102ae5780636352211e146102ce57806370a082311461030457600080fd5b806301ffc9a71461014557806306fdde031461017a578063081812fc1461019c578063095ea7b3146101ea57806318160ddd1461020c575b600080fd5b34801561015157600080fd5b506101656101603660046114a4565b6104a7565b60405190151581526020015b60405180910390f35b34801561018657600080fd5b5061018f6104f9565b6040516101719190611520565b3480156101a857600080fd5b506101d26101b7366004611533565b6004602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610171565b3480156101f657600080fd5b5061020a610205366004611568565b610587565b005b34801561021857600080fd5b5061022161066e565b604051908152602001610171565b34801561023b57600080fd5b5061020a61024a366004611592565b61067e565b34801561025b57600080fd5b5061026f61026a3660046115ce565b610845565b604080516001600160a01b039093168352602083019190915201610171565b34801561029a57600080fd5b5061020a6102a936600461168f565b61086d565b3480156102ba57600080fd5b5061020a6102c9366004611592565b6108ae565b3480156102da57600080fd5b506101d26102e9366004611533565b6003602052600090815260409020546001600160a01b031681565b34801561031057600080fd5b5061022161031f3660046116d8565b60026020526000908152604090205481565b34801561033d57600080fd5b5061020a610983565b34801561035257600080fd5b506007546001600160a01b03166101d2565b34801561037057600080fd5b5061018f6109b9565b34801561038557600080fd5b50610165610394366004611713565b6109c6565b3480156103a557600080fd5b5061020a6103b436600461168f565b610c02565b3480156103c557600080fd5b5061020a6103d43660046117a3565b610c3f565b61020a6103e7366004611713565b610cab565b3480156103f857600080fd5b5061020a6104073660046117df565b610d06565b34801561041857600080fd5b5061018f610427366004611533565b610dc8565b34801561043857600080fd5b50610165610447366004611847565b600560209081526000928352604080842090915290825290205460ff1681565b34801561047357600080fd5b5061020a6104823660046115ce565b610eca565b34801561049357600080fd5b5061020a6104a23660046116d8565b610f06565b60006301ffc9a760e01b6001600160e01b0319831614806104d857506380ac58cd60e01b6001600160e01b03198316145b806104f35750635b5e139f60e01b6001600160e01b03198316145b92915050565b600080546105069061187a565b80601f01602080910402602001604051908101604052809291908181526020018280546105329061187a565b801561057f5780601f106105545761010080835404028352916020019161057f565b820191906000526020600020905b81548152906001019060200180831161056257829003601f168201915b505050505081565b6000818152600360205260409020546001600160a01b0316338114806105d057506001600160a01b038116600090815260056020908152604080832033845290915290205460ff165b6106125760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064015b60405180910390fd5b60008281526004602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b600061067960085490565b905090565b6000818152600360205260409020546001600160a01b038481169116146106d45760405162461bcd60e51b815260206004820152600a60248201526957524f4e475f46524f4d60b01b6044820152606401610609565b6001600160a01b03821661071e5760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610609565b336001600160a01b038416148061074b57506000818152600460205260409020546001600160a01b031633145b8061077957506001600160a01b038316600090815260056020908152604080832033845290915290205460ff165b6107b65760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b6044820152606401610609565b6001600160a01b0380841660008181526002602090815260408083208054600019019055938616808352848320805460010190558583526003825284832080546001600160a01b03199081168317909155600490925284832080549092169091559251849392917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600a805460009182916001600160a01b03169061086290856118e0565b915091509250929050565b6007546001600160a01b031633146108975760405162461bcd60e51b8152600401610609906118f4565b80516108aa90600d9060208401906113f5565b5050565b6108b983838361067e565b6001600160a01b0382163b15806109625750604051630a85bd0160e11b8082523360048301526001600160a01b03858116602484015260448301849052608060648401526000608484015290919084169063150b7a029060a4016020604051808303816000875af1158015610932573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109569190611929565b6001600160e01b031916145b61097e5760405162461bcd60e51b815260040161060990611946565b505050565b6007546001600160a01b031633146109ad5760405162461bcd60e51b8152600401610609906118f4565b6109b76000610fae565b565b600180546105069061187a565b6000611068846109d560085490565b6109df9190611970565b11156109fe57604051632cdb04a160e21b815260040160405180910390fd5b85600414610a9c576000868152600e602052604090205415610a9457600082806020019051810190610a309190611988565b6040516bffffffffffffffffffffffff19606089901b166020820152909150600090603401604051602081830303815290604052805190602001209050610a8b82600e60008b81526020019081526020016000205483611000565b92505050610bf8565b506001610bf8565b6006546040516362bb919960e11b81526001600160a01b038781166004830152602482018a905263ffffffff89166044830152600092169063c577233290606401602060405180830381865afa158015610afa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b1e9190611a2e565b6006549091506000906001600160a01b03163314610b4557610b408287611970565b610b47565b815b9050610b54816019611a47565b610b6790683635c9adc5dea00000611a47565b6040516370a0823160e01b81526001600160a01b0389811660048301527f0000000000000000000000006fa5ff63b2752265c6bd9350591f97a7dad9e91816906370a0823190602401602060405180830381865afa158015610bcd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf19190611a2e565b1015925050505b9695505050505050565b6007546001600160a01b03163314610c2c5760405162461bcd60e51b8152600401610609906118f4565b80516108aa90600c9060208401906113f5565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b85610cb581611016565b610cc38787878787876109c6565b610ce057604051631eb49d6d60e11b815260040160405180910390fd5b60005b84811015610cfc57610cf486611081565b600101610ce3565b5050505050505050565b610d1184848461067e565b6001600160a01b0383163b1580610da65750604051630a85bd0160e11b808252906001600160a01b0385169063150b7a0290610d57903390899088908890600401611a66565b6020604051808303816000875af1158015610d76573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d9a9190611929565b6001600160e01b031916145b610dc25760405162461bcd60e51b815260040161060990611946565b50505050565b6060610dd360085490565b821115610df357604051636dac6a0960e01b815260040160405180910390fd5b6000600d8054610e029061187a565b905011610e9957600c8054610e169061187a565b80601f0160208091040260200160405190810160405280929190818152602001828054610e429061187a565b8015610e8f5780601f10610e6457610100808354040283529160200191610e8f565b820191906000526020600020905b815481529060010190602001808311610e7257829003601f168201915b50505050506104f3565b600d610ea4836110a1565b604051602001610eb5929190611ab5565b60405160208183030381529060405292915050565b6007546001600160a01b03163314610ef45760405162461bcd60e51b8152600401610609906118f4565b6000918252600e602052604090912055565b6007546001600160a01b03163314610f305760405162461bcd60e51b8152600401610609906118f4565b6001600160a01b038116610f955760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610609565b610f9e81610fae565b50565b80546001019055565b5490565b600780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60008261100d85846111aa565b14949350505050565b807f00000000000000000000000000000000000000000000000000000000000000011461105657604051632eafdb6960e01b815260040160405180910390fd5b6006546001600160a01b03163314610f9e576040516347322d0360e01b815260040160405180910390fd5b61108f600880546001019055565b610f9e8161109c60085490565b61121e565b6060816000036110c85750506040805180820190915260018152600360fc1b602082015290565b8160005b81156110f257806110dc81611b5b565b91506110eb9050600a836118e0565b91506110cc565b60008167ffffffffffffffff81111561110d5761110d6115f0565b6040519080825280601f01601f191660200182016040528015611137576020820181803683370190505b5090505b84156111a25761114c600183611b74565b9150611159600a86611b8b565b611164906030611970565b60f81b81838151811061117957611179611b9f565b60200101906001600160f81b031916908160001a90535061119b600a866118e0565b945061113b565b949350505050565b600081815b84518110156112165760008582815181106111cc576111cc611b9f565b602002602001015190508083116111f25760008381526020829052604090209250611203565b600081815260208490526040902092505b508061120e81611b5b565b9150506111af565b509392505050565b61122882826112ea565b6001600160a01b0382163b15806112ce5750604051630a85bd0160e11b80825233600483015260006024830181905260448301849052608060648401526084830152906001600160a01b0384169063150b7a029060a4016020604051808303816000875af115801561129e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112c29190611929565b6001600160e01b031916145b6108aa5760405162461bcd60e51b815260040161060990611946565b6001600160a01b0382166113345760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610609565b6000818152600360205260409020546001600160a01b03161561138a5760405162461bcd60e51b815260206004820152600e60248201526d1053149150511657d3525395115160921b6044820152606401610609565b6001600160a01b038216600081815260026020908152604080832080546001019055848352600390915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b8280546114019061187a565b90600052602060002090601f0160209004810192826114235760008555611469565b82601f1061143c57805160ff1916838001178555611469565b82800160010185558215611469579182015b8281111561146957825182559160200191906001019061144e565b50611475929150611479565b5090565b5b80821115611475576000815560010161147a565b6001600160e01b031981168114610f9e57600080fd5b6000602082840312156114b657600080fd5b81356114c18161148e565b9392505050565b60005b838110156114e35781810151838201526020016114cb565b83811115610dc25750506000910152565b6000815180845261150c8160208601602086016114c8565b601f01601f19169290920160200192915050565b6020815260006114c160208301846114f4565b60006020828403121561154557600080fd5b5035919050565b80356001600160a01b038116811461156357600080fd5b919050565b6000806040838503121561157b57600080fd5b6115848361154c565b946020939093013593505050565b6000806000606084860312156115a757600080fd5b6115b08461154c565b92506115be6020850161154c565b9150604084013590509250925092565b600080604083850312156115e157600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561162f5761162f6115f0565b604052919050565b600067ffffffffffffffff831115611651576116516115f0565b611664601f8401601f1916602001611606565b905082815283838301111561167857600080fd5b828260208301376000602084830101529392505050565b6000602082840312156116a157600080fd5b813567ffffffffffffffff8111156116b857600080fd5b8201601f810184136116c957600080fd5b6111a284823560208401611637565b6000602082840312156116ea57600080fd5b6114c18261154c565b600082601f83011261170457600080fd5b6114c183833560208501611637565b60008060008060008060c0878903121561172c57600080fd5b86359550602087013594506117436040880161154c565b935060608701359250608087013567ffffffffffffffff8082111561176757600080fd5b6117738a838b016116f3565b935060a089013591508082111561178957600080fd5b5061179689828a016116f3565b9150509295509295509295565b600080604083850312156117b657600080fd5b6117bf8361154c565b9150602083013580151581146117d457600080fd5b809150509250929050565b600080600080608085870312156117f557600080fd5b6117fe8561154c565b935061180c6020860161154c565b925060408501359150606085013567ffffffffffffffff81111561182f57600080fd5b61183b878288016116f3565b91505092959194509250565b6000806040838503121561185a57600080fd5b6118638361154c565b91506118716020840161154c565b90509250929050565b600181811c9082168061188e57607f821691505b6020821081036118ae57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000826118ef576118ef6118b4565b500490565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60006020828403121561193b57600080fd5b81516114c18161148e565b60208082526010908201526f155394d0519157d49150d2541251539560821b604082015260600190565b60008219821115611983576119836118ca565b500190565b6000602080838503121561199b57600080fd5b825167ffffffffffffffff808211156119b357600080fd5b818501915085601f8301126119c757600080fd5b8151818111156119d9576119d96115f0565b8060051b91506119ea848301611606565b8181529183018401918481019088841115611a0457600080fd5b938501935b83851015611a2257845182529385019390850190611a09565b98975050505050505050565b600060208284031215611a4057600080fd5b5051919050565b6000816000190483118215151615611a6157611a616118ca565b500290565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090610bf8908301846114f4565b60008151611aab8185602086016114c8565b9290920192915050565b600080845481600182811c915080831680611ad157607f831692505b60208084108203611af057634e487b7160e01b86526022600452602486fd5b818015611b045760018114611b1557611b42565b60ff19861689528489019650611b42565b60008b81526020902060005b86811015611b3a5781548b820152908501908301611b21565b505084890196505b505050505050611b528185611a99565b95945050505050565b600060018201611b6d57611b6d6118ca565b5060010190565b600082821015611b8657611b866118ca565b500390565b600082611b9a57611b9a6118b4565b500690565b634e487b7160e01b600052603260045260246000fdfea264697066735822122076ff48df4e89b9cee327b28a5c896938e051cc308853ee760ec50cd3818668c164736f6c634300080d0033

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

00000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001000000000000000000000000006fa5ff63b2752265c6bd9350591f97a7dad9e91800000000000000000000000021da1b084175f95285b49b22c018889c45e1820d000000000000000000000000689bba0e25c259b205ece8e6152ee1eacf307f5f0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000d536c6963652047656e65736973000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003534c470000000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : name_ (string): Slice Genesis
Arg [1] : symbol_ (string): SLG
Arg [2] : slxAddress_ (address): 0x6fa5FF63B2752265c6Bd9350591f97A7dAd9e918
Arg [3] : sliceCoreAddress_ (address): 0x21da1b084175f95285B49b22C018889c45E1820d
Arg [4] : productsModuleAddress_ (address): 0x689Bba0e25c259b205ECe8e6152Ee1eAcF307f5F
Arg [5] : slicerId_ (uint256): 1

-----Encoded View---------------
10 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [2] : 0000000000000000000000006fa5ff63b2752265c6bd9350591f97a7dad9e918
Arg [3] : 00000000000000000000000021da1b084175f95285b49b22c018889c45e1820d
Arg [4] : 000000000000000000000000689bba0e25c259b205ece8e6152ee1eacf307f5f
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [6] : 000000000000000000000000000000000000000000000000000000000000000d
Arg [7] : 536c6963652047656e6573697300000000000000000000000000000000000000
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [9] : 534c470000000000000000000000000000000000000000000000000000000000


Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.