ETH Price: $2,628.43 (-0.09%)
Gas: 2 Gwei

Contract

0x0Ce293f18677015D42a5764fC98F59332ECC72DF
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
0x60806040166057462023-02-11 13:14:23547 days ago1676121263IN
 Create: SquishiBoundToken
0 ETH0.0320854718.58286619

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
SquishiBoundToken

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 34 : SquishiBoundToken.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

import {IERC1155, TrackableBurnableERC1155} from "../extensions/ERC1155/TrackableBurnableERC1155.sol";

/**
 * @title SquishiBoundToken
 * @custom:website www.squishiverse.com
 * @author Lozz (@lozzereth / www.allthingsweb3.com)
 * @notice Squishiverse "SquishiBound" Soul-Bound Token (SBT) implementation contract.
 */
contract SquishiBoundToken is TrackableBurnableERC1155 {
    /// @dev Thrown when an approval is made while untransferable
    error Unapprovable();

    /// @dev Thrown when making an transfer while untransferable
    error Untransferable();

    function initialize(string memory _metadataUri) public initializer {
        __TrackableBurnableERC1155_init(
            "SquishiBound Token",
            "SBT",
            _metadataUri
        );
    }

    /**
     * @inheritdoc TrackableBurnableERC1155
     */
    function burn(
        address account,
        uint256 id,
        uint256 value
    )
        public
        virtual
        override(TrackableBurnableERC1155)
        ownerOrApproved(account)
    {
        super.burn(account, id, value);
    }

    /**
     * @notice Airdrop to specified addresses
     * @param accounts Account addresses
     * @param id Token id to airdrop
     * @param quantity Quantity to airdrop
     */
    function airdrop(
        address[] memory accounts,
        uint256 id,
        uint256 quantity
    ) external onlyOwner {
        for (uint256 i; i < accounts.length; i++) {
            _mint(accounts[i], id, quantity, "");
        }
    }

    /**
     * @inheritdoc IERC1155
     */
    function setApprovalForAll(address, bool) public pure override {
        revert Unapprovable();
    }

    /**
     * @inheritdoc IERC1155
     */
    function safeTransferFrom(
        address,
        address,
        uint256,
        uint256,
        bytes memory
    ) public pure override {
        revert Untransferable();
    }

    /**
     * @inheritdoc IERC1155
     */
    function safeBatchTransferFrom(
        address,
        address,
        uint256[] memory,
        uint256[] memory,
        bytes memory
    ) public virtual override {
        revert Untransferable();
    }
}

File 2 of 34 : IOwnable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

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

interface IOwnable is IERC173 {}

File 3 of 34 : 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 4 of 34 : 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 5 of 34 : 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 6 of 34 : 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 7 of 34 : IERC1155.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

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

/**
 * @title ERC1155 interface
 * @dev see https://github.com/ethereum/EIPs/issues/1155
 */
interface IERC1155 is IERC1155Internal, IERC165 {
    /**
     * @notice query the balance of given token held by given address
     * @param account address to query
     * @param id token to query
     * @return token balance
     */
    function balanceOf(
        address account,
        uint256 id
    ) external view returns (uint256);

    /**
     * @notice query the balances of given tokens held by given addresses
     * @param accounts addresss to query
     * @param ids tokens to query
     * @return token balances
     */
    function balanceOfBatch(
        address[] calldata accounts,
        uint256[] calldata ids
    ) external view returns (uint256[] memory);

    /**
     * @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 whether operator is approved to spend tokens held by account
     */
    function isApprovedForAll(
        address account,
        address operator
    ) external view returns (bool);

    /**
     * @notice grant approval to or revoke approval from given operator to spend held tokens
     * @param operator address whose approval status to update
     * @param status whether operator should be considered approved
     */
    function setApprovalForAll(address operator, bool status) external;

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

    /**
     * @notice transfer batch of tokens between given addresses, checking for ERC1155Receiver implementation if applicable
     * @param from sender of tokens
     * @param to receiver of tokens
     * @param ids list of token IDs
     * @param amounts list of quantities of tokens to transfer
     * @param data data payload
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata amounts,
        bytes calldata data
    ) external;
}

File 8 of 34 : IERC1155Internal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

/**
 * @title Partial ERC1155 interface needed by internal functions
 */
interface IERC1155Internal {
    event TransferSingle(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256 id,
        uint256 value
    );

    event TransferBatch(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256[] ids,
        uint256[] values
    );

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

File 9 of 34 : IERC1155Receiver.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

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

/**
 * @title ERC1155 transfer receiver interface
 */
interface IERC1155Receiver is IERC165 {
    /**
     * @notice validate receipt of ERC1155 transfer
     * @param operator executor of transfer
     * @param from sender of tokens
     * @param id token ID received
     * @param value quantity of tokens received
     * @param data data payload
     * @return function's own selector if transfer is accepted
     */
    function onERC1155Received(
        address operator,
        address from,
        uint256 id,
        uint256 value,
        bytes calldata data
    ) external returns (bytes4);

    /**
     * @notice validate receipt of ERC1155 batch transfer
     * @param operator executor of transfer
     * @param from sender of tokens
     * @param ids token IDs received
     * @param values quantities of tokens received
     * @param data data payload
     * @return function's own selector if transfer is accepted
     */
    function onERC1155BatchReceived(
        address operator,
        address from,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    ) external returns (bytes4);
}

File 10 of 34 : 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 11 of 34 : IERC165Internal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

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

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

}

File 12 of 34 : 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 conrtact 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 13 of 34 : 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 14 of 34 : 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 15 of 34 : 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 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 {
        if (interfaceId == 0xffffffff) revert ERC165Base__InvalidInterfaceId();
        ERC165BaseStorage.layout().supportedInterfaces[interfaceId] = status;
    }
}

File 16 of 34 : 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 17 of 34 : 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 18 of 34 : 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 19 of 34 : ERC1155Base.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IERC1155 } from '../../../interfaces/IERC1155.sol';
import { IERC1155Receiver } from '../../../interfaces/IERC1155Receiver.sol';
import { IERC1155Base } from './IERC1155Base.sol';
import { ERC1155BaseInternal, ERC1155BaseStorage } from './ERC1155BaseInternal.sol';

/**
 * @title Base ERC1155 contract
 * @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts/ (MIT license)
 */
abstract contract ERC1155Base is IERC1155Base, ERC1155BaseInternal {
    /**
     * @inheritdoc IERC1155
     */
    function balanceOf(
        address account,
        uint256 id
    ) public view virtual returns (uint256) {
        return _balanceOf(account, id);
    }

    /**
     * @inheritdoc IERC1155
     */
    function balanceOfBatch(
        address[] memory accounts,
        uint256[] memory ids
    ) public view virtual returns (uint256[] memory) {
        if (accounts.length != ids.length)
            revert ERC1155Base__ArrayLengthMismatch();

        mapping(uint256 => mapping(address => uint256))
            storage balances = ERC1155BaseStorage.layout().balances;

        uint256[] memory batchBalances = new uint256[](accounts.length);

        unchecked {
            for (uint256 i; i < accounts.length; i++) {
                if (accounts[i] == address(0))
                    revert ERC1155Base__BalanceQueryZeroAddress();
                batchBalances[i] = balances[ids[i]][accounts[i]];
            }
        }

        return batchBalances;
    }

    /**
     * @inheritdoc IERC1155
     */
    function isApprovedForAll(
        address account,
        address operator
    ) public view virtual returns (bool) {
        return ERC1155BaseStorage.layout().operatorApprovals[account][operator];
    }

    /**
     * @inheritdoc IERC1155
     */
    function setApprovalForAll(address operator, bool status) public virtual {
        if (msg.sender == operator) revert ERC1155Base__SelfApproval();
        ERC1155BaseStorage.layout().operatorApprovals[msg.sender][
            operator
        ] = status;
        emit ApprovalForAll(msg.sender, operator, status);
    }

    /**
     * @inheritdoc IERC1155
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) public virtual {
        if (from != msg.sender && !isApprovedForAll(from, msg.sender))
            revert ERC1155Base__NotOwnerOrApproved();
        _safeTransfer(msg.sender, from, to, id, amount, data);
    }

    /**
     * @inheritdoc IERC1155
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) public virtual {
        if (from != msg.sender && !isApprovedForAll(from, msg.sender))
            revert ERC1155Base__NotOwnerOrApproved();
        _safeTransferBatch(msg.sender, from, to, ids, amounts, data);
    }
}

File 20 of 34 : ERC1155BaseInternal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IERC1155Receiver } from '../../../interfaces/IERC1155Receiver.sol';
import { AddressUtils } from '../../../utils/AddressUtils.sol';
import { IERC1155BaseInternal } from './IERC1155BaseInternal.sol';
import { ERC1155BaseStorage } from './ERC1155BaseStorage.sol';

/**
 * @title Base ERC1155 internal functions
 * @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts/ (MIT license)
 */
abstract contract ERC1155BaseInternal is IERC1155BaseInternal {
    using AddressUtils for address;

    /**
     * @notice query the balance of given token held by given address
     * @param account address to query
     * @param id token to query
     * @return token balance
     */
    function _balanceOf(
        address account,
        uint256 id
    ) internal view virtual returns (uint256) {
        if (account == address(0))
            revert ERC1155Base__BalanceQueryZeroAddress();
        return ERC1155BaseStorage.layout().balances[id][account];
    }

    /**
     * @notice mint given quantity of tokens for given address
     * @dev ERC1155Receiver implementation is not checked
     * @param account beneficiary of minting
     * @param id token ID
     * @param amount quantity of tokens to mint
     * @param data data payload
     */
    function _mint(
        address account,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) internal virtual {
        if (account == address(0)) revert ERC1155Base__MintToZeroAddress();

        _beforeTokenTransfer(
            msg.sender,
            address(0),
            account,
            _asSingletonArray(id),
            _asSingletonArray(amount),
            data
        );

        ERC1155BaseStorage.layout().balances[id][account] += amount;

        emit TransferSingle(msg.sender, address(0), account, id, amount);
    }

    /**
     * @notice mint given quantity of tokens for given address
     * @param account beneficiary of minting
     * @param id token ID
     * @param amount quantity of tokens to mint
     * @param data data payload
     */
    function _safeMint(
        address account,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) internal virtual {
        _mint(account, id, amount, data);

        _doSafeTransferAcceptanceCheck(
            msg.sender,
            address(0),
            account,
            id,
            amount,
            data
        );
    }

    /**
     * @notice mint batch of tokens for given address
     * @dev ERC1155Receiver implementation is not checked
     * @param account beneficiary of minting
     * @param ids list of token IDs
     * @param amounts list of quantities of tokens to mint
     * @param data data payload
     */
    function _mintBatch(
        address account,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {
        if (account == address(0)) revert ERC1155Base__MintToZeroAddress();
        if (ids.length != amounts.length)
            revert ERC1155Base__ArrayLengthMismatch();

        _beforeTokenTransfer(
            msg.sender,
            address(0),
            account,
            ids,
            amounts,
            data
        );

        mapping(uint256 => mapping(address => uint256))
            storage balances = ERC1155BaseStorage.layout().balances;

        for (uint256 i; i < ids.length; ) {
            balances[ids[i]][account] += amounts[i];
            unchecked {
                i++;
            }
        }

        emit TransferBatch(msg.sender, address(0), account, ids, amounts);
    }

    /**
     * @notice mint batch of tokens for given address
     * @param account beneficiary of minting
     * @param ids list of token IDs
     * @param amounts list of quantities of tokens to mint
     * @param data data payload
     */
    function _safeMintBatch(
        address account,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {
        _mintBatch(account, ids, amounts, data);

        _doSafeBatchTransferAcceptanceCheck(
            msg.sender,
            address(0),
            account,
            ids,
            amounts,
            data
        );
    }

    /**
     * @notice burn given quantity of tokens held by given address
     * @param account holder of tokens to burn
     * @param id token ID
     * @param amount quantity of tokens to burn
     */
    function _burn(
        address account,
        uint256 id,
        uint256 amount
    ) internal virtual {
        if (account == address(0)) revert ERC1155Base__BurnFromZeroAddress();

        _beforeTokenTransfer(
            msg.sender,
            account,
            address(0),
            _asSingletonArray(id),
            _asSingletonArray(amount),
            ''
        );

        mapping(address => uint256) storage balances = ERC1155BaseStorage
            .layout()
            .balances[id];

        unchecked {
            if (amount > balances[account])
                revert ERC1155Base__BurnExceedsBalance();
            balances[account] -= amount;
        }

        emit TransferSingle(msg.sender, account, address(0), id, amount);
    }

    /**
     * @notice burn given batch of tokens held by given address
     * @param account holder of tokens to burn
     * @param ids token IDs
     * @param amounts quantities of tokens to burn
     */
    function _burnBatch(
        address account,
        uint256[] memory ids,
        uint256[] memory amounts
    ) internal virtual {
        if (account == address(0)) revert ERC1155Base__BurnFromZeroAddress();
        if (ids.length != amounts.length)
            revert ERC1155Base__ArrayLengthMismatch();

        _beforeTokenTransfer(msg.sender, account, address(0), ids, amounts, '');

        mapping(uint256 => mapping(address => uint256))
            storage balances = ERC1155BaseStorage.layout().balances;

        unchecked {
            for (uint256 i; i < ids.length; i++) {
                uint256 id = ids[i];
                if (amounts[i] > balances[id][account])
                    revert ERC1155Base__BurnExceedsBalance();
                balances[id][account] -= amounts[i];
            }
        }

        emit TransferBatch(msg.sender, account, address(0), ids, amounts);
    }

    /**
     * @notice transfer tokens between given addresses
     * @dev ERC1155Receiver implementation is not checked
     * @param operator executor of transfer
     * @param sender sender of tokens
     * @param recipient receiver of tokens
     * @param id token ID
     * @param amount quantity of tokens to transfer
     * @param data data payload
     */
    function _transfer(
        address operator,
        address sender,
        address recipient,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) internal virtual {
        if (recipient == address(0))
            revert ERC1155Base__TransferToZeroAddress();

        _beforeTokenTransfer(
            operator,
            sender,
            recipient,
            _asSingletonArray(id),
            _asSingletonArray(amount),
            data
        );

        mapping(uint256 => mapping(address => uint256))
            storage balances = ERC1155BaseStorage.layout().balances;

        unchecked {
            uint256 senderBalance = balances[id][sender];
            if (amount > senderBalance)
                revert ERC1155Base__TransferExceedsBalance();
            balances[id][sender] = senderBalance - amount;
        }

        balances[id][recipient] += amount;

        emit TransferSingle(operator, sender, recipient, id, amount);
    }

    /**
     * @notice transfer tokens between given addresses
     * @param operator executor of transfer
     * @param sender sender of tokens
     * @param recipient receiver of tokens
     * @param id token ID
     * @param amount quantity of tokens to transfer
     * @param data data payload
     */
    function _safeTransfer(
        address operator,
        address sender,
        address recipient,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) internal virtual {
        _transfer(operator, sender, recipient, id, amount, data);

        _doSafeTransferAcceptanceCheck(
            operator,
            sender,
            recipient,
            id,
            amount,
            data
        );
    }

    /**
     * @notice transfer batch of tokens between given addresses
     * @dev ERC1155Receiver implementation is not checked
     * @param operator executor of transfer
     * @param sender sender of tokens
     * @param recipient receiver of tokens
     * @param ids token IDs
     * @param amounts quantities of tokens to transfer
     * @param data data payload
     */
    function _transferBatch(
        address operator,
        address sender,
        address recipient,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {
        if (recipient == address(0))
            revert ERC1155Base__TransferToZeroAddress();
        if (ids.length != amounts.length)
            revert ERC1155Base__ArrayLengthMismatch();

        _beforeTokenTransfer(operator, sender, recipient, ids, amounts, data);

        mapping(uint256 => mapping(address => uint256))
            storage balances = ERC1155BaseStorage.layout().balances;

        for (uint256 i; i < ids.length; ) {
            uint256 token = ids[i];
            uint256 amount = amounts[i];

            unchecked {
                uint256 senderBalance = balances[token][sender];

                if (amount > senderBalance)
                    revert ERC1155Base__TransferExceedsBalance();

                balances[token][sender] = senderBalance - amount;

                i++;
            }

            // balance increase cannot be unchecked because ERC1155Base neither tracks nor validates a totalSupply
            balances[token][recipient] += amount;
        }

        emit TransferBatch(operator, sender, recipient, ids, amounts);
    }

    /**
     * @notice transfer batch of tokens between given addresses
     * @param operator executor of transfer
     * @param sender sender of tokens
     * @param recipient receiver of tokens
     * @param ids token IDs
     * @param amounts quantities of tokens to transfer
     * @param data data payload
     */
    function _safeTransferBatch(
        address operator,
        address sender,
        address recipient,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {
        _transferBatch(operator, sender, recipient, ids, amounts, data);

        _doSafeBatchTransferAcceptanceCheck(
            operator,
            sender,
            recipient,
            ids,
            amounts,
            data
        );
    }

    /**
     * @notice wrap given element in array of length 1
     * @param element element to wrap
     * @return singleton array
     */
    function _asSingletonArray(
        uint256 element
    ) private pure returns (uint256[] memory) {
        uint256[] memory array = new uint256[](1);
        array[0] = element;
        return array;
    }

    /**
     * @notice revert if applicable transfer recipient is not valid ERC1155Receiver
     * @param operator executor of transfer
     * @param from sender of tokens
     * @param to receiver of tokens
     * @param id token ID
     * @param amount quantity of tokens to transfer
     * @param data data payload
     */
    function _doSafeTransferAcceptanceCheck(
        address operator,
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) private {
        if (to.isContract()) {
            try
                IERC1155Receiver(to).onERC1155Received(
                    operator,
                    from,
                    id,
                    amount,
                    data
                )
            returns (bytes4 response) {
                if (response != IERC1155Receiver.onERC1155Received.selector)
                    revert ERC1155Base__ERC1155ReceiverRejected();
            } catch Error(string memory reason) {
                revert(reason);
            } catch {
                revert ERC1155Base__ERC1155ReceiverNotImplemented();
            }
        }
    }

    /**
     * @notice revert if applicable transfer recipient is not valid ERC1155Receiver
     * @param operator executor of transfer
     * @param from sender of tokens
     * @param to receiver of tokens
     * @param ids token IDs
     * @param amounts quantities of tokens to transfer
     * @param data data payload
     */
    function _doSafeBatchTransferAcceptanceCheck(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) private {
        if (to.isContract()) {
            try
                IERC1155Receiver(to).onERC1155BatchReceived(
                    operator,
                    from,
                    ids,
                    amounts,
                    data
                )
            returns (bytes4 response) {
                if (
                    response != IERC1155Receiver.onERC1155BatchReceived.selector
                ) revert ERC1155Base__ERC1155ReceiverRejected();
            } catch Error(string memory reason) {
                revert(reason);
            } catch {
                revert ERC1155Base__ERC1155ReceiverNotImplemented();
            }
        }
    }

    /**
     * @notice ERC1155 hook, called before all transfers including mint and burn
     * @dev function should be overridden and new implementation must call super
     * @dev called for both single and batch transfers
     * @param operator executor of transfer
     * @param from sender of tokens
     * @param to receiver of tokens
     * @param ids token IDs
     * @param amounts quantities of tokens to transfer
     * @param data data payload
     */
    function _beforeTokenTransfer(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {}
}

File 21 of 34 : ERC1155BaseStorage.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

library ERC1155BaseStorage {
    struct Layout {
        mapping(uint256 => mapping(address => uint256)) balances;
        mapping(address => mapping(address => bool)) operatorApprovals;
    }

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

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

File 22 of 34 : IERC1155Base.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IERC1155 } from '../../../interfaces/IERC1155.sol';
import { IERC1155BaseInternal } from './IERC1155BaseInternal.sol';

/**
 * @title ERC1155 base interface
 */
interface IERC1155Base is IERC1155BaseInternal, IERC1155 {

}

File 23 of 34 : IERC1155BaseInternal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

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

/**
 * @title ERC1155 base interface
 */
interface IERC1155BaseInternal is IERC1155Internal {
    error ERC1155Base__ArrayLengthMismatch();
    error ERC1155Base__BalanceQueryZeroAddress();
    error ERC1155Base__NotOwnerOrApproved();
    error ERC1155Base__SelfApproval();
    error ERC1155Base__BurnExceedsBalance();
    error ERC1155Base__BurnFromZeroAddress();
    error ERC1155Base__ERC1155ReceiverRejected();
    error ERC1155Base__ERC1155ReceiverNotImplemented();
    error ERC1155Base__MintToZeroAddress();
    error ERC1155Base__TransferExceedsBalance();
    error ERC1155Base__TransferToZeroAddress();
}

File 24 of 34 : ERC1155Metadata.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { UintUtils } from '../../../utils/UintUtils.sol';
import { IERC1155Metadata } from './IERC1155Metadata.sol';
import { ERC1155MetadataInternal } from './ERC1155MetadataInternal.sol';
import { ERC1155MetadataStorage } from './ERC1155MetadataStorage.sol';

/**
 * @title ERC1155 metadata extensions
 */
abstract contract ERC1155Metadata is IERC1155Metadata, ERC1155MetadataInternal {
    using UintUtils for uint256;

    /**
     * @notice inheritdoc IERC1155Metadata
     */
    function uri(uint256 tokenId) public view virtual returns (string memory) {
        ERC1155MetadataStorage.Layout storage l = ERC1155MetadataStorage
            .layout();

        string memory tokenIdURI = l.tokenURIs[tokenId];
        string memory baseURI = l.baseURI;

        if (bytes(baseURI).length == 0) {
            return tokenIdURI;
        } else if (bytes(tokenIdURI).length > 0) {
            return string(abi.encodePacked(baseURI, tokenIdURI));
        } else {
            return string(abi.encodePacked(baseURI, tokenId.toString()));
        }
    }
}

File 25 of 34 : ERC1155MetadataInternal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IERC1155MetadataInternal } from './IERC1155MetadataInternal.sol';
import { ERC1155MetadataStorage } from './ERC1155MetadataStorage.sol';

/**
 * @title ERC1155Metadata internal functions
 */
abstract contract ERC1155MetadataInternal is IERC1155MetadataInternal {
    /**
     * @notice set base metadata URI
     * @dev base URI is a non-standard feature adapted from the ERC721 specification
     * @param baseURI base URI
     */
    function _setBaseURI(string memory baseURI) internal {
        ERC1155MetadataStorage.layout().baseURI = baseURI;
    }

    /**
     * @notice set per-token metadata URI
     * @param tokenId token whose metadata URI to set
     * @param tokenURI per-token URI
     */
    function _setTokenURI(uint256 tokenId, string memory tokenURI) internal {
        ERC1155MetadataStorage.layout().tokenURIs[tokenId] = tokenURI;
        emit URI(tokenURI, tokenId);
    }
}

File 26 of 34 : ERC1155MetadataStorage.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

/**
 * @title ERC1155 metadata extensions
 */
library ERC1155MetadataStorage {
    bytes32 internal constant STORAGE_SLOT =
        keccak256('solidstate.contracts.storage.ERC1155Metadata');

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

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

File 27 of 34 : IERC1155Metadata.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

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

/**
 * @title ERC1155Metadata interface
 */
interface IERC1155Metadata is IERC1155MetadataInternal {
    /**
     * @notice get generated URI for given token
     * @return token URI
     */
    function uri(uint256 tokenId) external view returns (string memory);
}

File 28 of 34 : IERC1155MetadataInternal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

/**
 * @title Partial ERC1155Metadata interface needed by internal functions
 */
interface IERC1155MetadataInternal {
    event URI(string value, uint256 indexed tokenId);
}

File 29 of 34 : 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 30 of 34 : 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 31 of 34 : TrackableBurnableERC1155.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8;

import {Ownable} from "@solidstate-solidity/access/ownable/Ownable.sol";
import {ERC1155Base} from "@solidstate-solidity/token/ERC1155/base/ERC1155Base.sol";
import {ERC1155Metadata} from "@solidstate-solidity/token/ERC1155/metadata/ERC1155Metadata.sol";
import {ERC165Base} from "@solidstate-solidity/introspection/ERC165/base/ERC165Base.sol";
import {IERC165} from "@solidstate-solidity/interfaces/IERC165.sol";
import {IERC1155} from "@solidstate-solidity/interfaces/IERC1155.sol";
import {TrackableBurnableERC1155Storage} from "./TrackableBurnableERC1155Storage.sol";
import {TrackableBurnableERC1155__Initializable} from "./TrackableBurnableERC1155__Initializable.sol";

/**
 * @title TrackableBurnableERC1155
 * @author Lozz (@lozzereth / www.allthingsweb3.com)
 * @notice Upgradeable ERC1155 implementation with burn, metadata and supply functionality
 *         added by default.
 */
abstract contract TrackableBurnableERC1155 is
    TrackableBurnableERC1155__Initializable,
    ERC165Base,
    ERC1155Base,
    ERC1155Metadata,
    Ownable
{
    function __TrackableBurnableERC1155_init(
        string memory name_,
        string memory symbol_,
        string memory baseURI_
    ) internal onlyInitializing {
        __TrackableBurnableERC1155_init_unchained(name_, symbol_, baseURI_);
    }

    function __TrackableBurnableERC1155_init_unchained(
        string memory name_,
        string memory symbol_,
        string memory baseURI_
    ) internal onlyInitializing {
        _setBaseURI(baseURI_);
        _setSupportsInterface(type(IERC165).interfaceId, true);
        _setSupportsInterface(type(IERC1155).interfaceId, true);
        TrackableBurnableERC1155Storage.layout().name = name_;
        TrackableBurnableERC1155Storage.layout().symbol = symbol_;
    }

    /**
     * @dev Total amount of tokens in with a given id.
     */
    function totalSupply(uint256 id) public view virtual returns (uint256) {
        return TrackableBurnableERC1155Storage.layout().totalSupply[id];
    }

    /**
     * @dev Indicates whether any token exist with a given id, or not.
     */
    function exists(uint256 id) public view virtual returns (bool) {
        return TrackableBurnableERC1155.totalSupply(id) > 0;
    }

    /**
     * @dev Name of the token
     */
    function name() public view virtual returns (string memory) {
        return TrackableBurnableERC1155Storage.layout().name;
    }

    /**
     * @dev Symbol of the token
     */
    function symbol() public view virtual returns (string memory) {
        return TrackableBurnableERC1155Storage.layout().symbol;
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning, as well as batched variants
     */
    function _beforeTokenTransfer(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual override {
        super._beforeTokenTransfer(operator, from, to, ids, amounts, data);

        if (from == address(0)) {
            for (uint256 i = 0; i < ids.length; ++i) {
                TrackableBurnableERC1155Storage.layout().totalSupply[
                        ids[i]
                    ] += amounts[i];
            }
        }

        if (to == address(0)) {
            for (uint256 i = 0; i < ids.length; ++i) {
                uint256 id = ids[i];
                uint256 amount = amounts[i];
                uint256 supply = TrackableBurnableERC1155Storage
                    .layout()
                    .totalSupply[id];
                require(
                    supply >= amount,
                    "ERC1155: burn amount exceeds totalSupply"
                );
                unchecked {
                    TrackableBurnableERC1155Storage.layout().totalSupply[id] =
                        supply -
                        amount;
                }
            }
        }
    }

    /**
     * @notice Burn an NFT
     */
    function burn(
        address account,
        uint256 id,
        uint256 value
    ) public virtual ownerOrApproved(account) {
        _burn(account, id, value);
    }

    /**
     * @notice Burn a batch of NFTs
     */
    function burnBatch(
        address account,
        uint256[] memory ids,
        uint256[] memory values
    ) public virtual ownerOrApproved(account) {
        _burnBatch(account, ids, values);
    }

    /**
     * @dev Modifier to track if a user is owner or approved
     */
    modifier ownerOrApproved(address account) {
        require(
            account == msg.sender || isApprovedForAll(account, msg.sender),
            "ERC1155: caller is not token owner or approved"
        );
        _;
    }

    /**
     * @dev Modify base URI as contract owner
     */
    function setBaseURI(string memory baseURI_) external onlyOwner {
        _setBaseURI(baseURI_);
    }
}

File 32 of 34 : TrackableBurnableERC1155Storage.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

library TrackableBurnableERC1155Storage {
    struct Layout {
        /// @dev Token name
        string name;
        /// @dev Token symbol
        string symbol;
        /// @dev Total supply for each token
        mapping(uint256 => uint256) totalSupply;
    }

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

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

File 33 of 34 : TrackableBurnableERC1155__Initializable.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8;

import {TrackableBurnableERC1155__InitializableStorage} from "./TrackableBurnableERC1155__InitializableStorage.sol";

abstract contract TrackableBurnableERC1155__Initializable {
    using TrackableBurnableERC1155__InitializableStorage for TrackableBurnableERC1155__InitializableStorage.Layout;

    /**
     * @dev Modifier to protect an initializer function from being invoked twice.
     */
    modifier initializer() {
        require(
            TrackableBurnableERC1155__InitializableStorage
                .layout()
                ._initializing
                ? _isConstructor()
                : !TrackableBurnableERC1155__InitializableStorage
                    .layout()
                    ._initialized,
            "TrackableBurnableERC1155__Initializable: contract is already initialized"
        );

        bool isTopLevelCall = !TrackableBurnableERC1155__InitializableStorage
            .layout()
            ._initializing;
        if (isTopLevelCall) {
            TrackableBurnableERC1155__InitializableStorage
                .layout()
                ._initializing = true;
            TrackableBurnableERC1155__InitializableStorage
                .layout()
                ._initialized = true;
        }

        _;

        if (isTopLevelCall) {
            TrackableBurnableERC1155__InitializableStorage
                .layout()
                ._initializing = false;
        }
    }

    /**
     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
     * {initializer} modifier, directly or indirectly.
     */
    modifier onlyInitializing() {
        require(
            TrackableBurnableERC1155__InitializableStorage
                .layout()
                ._initializing,
            "TrackableBurnableERC1155__Initializable: contract is not initializing"
        );
        _;
    }

    /// @dev Returns true if and only if the function is running in the constructor
    function _isConstructor() private view returns (bool) {
        // extcodesize checks the size of the code stored in an address, and
        // address returns the current address. Since the code is still not
        // deployed when running a constructor, any checks on its code size will
        // yield zero, making it an effective way to detect if a contract is
        // under construction or not.
        address self = address(this);
        uint256 cs;
        assembly {
            cs := extcodesize(self)
        }
        return cs == 0;
    }
}

File 34 of 34 : TrackableBurnableERC1155__InitializableStorage.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

library TrackableBurnableERC1155__InitializableStorage {
    struct Layout {
        bool _initialized;
        bool _initializing;
    }

    bytes32 internal constant STORAGE_SLOT =
        keccak256("trackableburnableerc1155.contracts.storage.initializable");

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

Settings
{
  "remappings": [
    "@closedsea/=lib/closedsea/src/",
    "@openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
    "@openzeppelin/=lib/openzeppelin-contracts/",
    "@prb/test/=lib/prb-test/src/",
    "@solady/=lib/solady/src/",
    "@solidstate-solidity/=lib/solidstate-solidity/contracts/",
    "@std/=lib/forge-std/src/",
    "closedsea/=lib/closedsea/src/",
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
    "erc721a-upgradeable/=lib/closedsea/lib/erc721a-upgradeable/contracts/",
    "erc721a/=lib/closedsea/lib/erc721a/contracts/",
    "forge-std/=lib/forge-std/src/",
    "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/",
    "operator-filter-registry/=lib/closedsea/lib/operator-filter-registry/src/",
    "solady/=lib/solady/src/",
    "solidstate-solidity/=lib/solidstate-solidity/contracts/",
    "solmate/=lib/solady/lib/solmate/src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "bytecodeHash": "ipfs"
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "london",
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[],"name":"ERC1155Base__ArrayLengthMismatch","type":"error"},{"inputs":[],"name":"ERC1155Base__BalanceQueryZeroAddress","type":"error"},{"inputs":[],"name":"ERC1155Base__BurnExceedsBalance","type":"error"},{"inputs":[],"name":"ERC1155Base__BurnFromZeroAddress","type":"error"},{"inputs":[],"name":"ERC1155Base__ERC1155ReceiverNotImplemented","type":"error"},{"inputs":[],"name":"ERC1155Base__ERC1155ReceiverRejected","type":"error"},{"inputs":[],"name":"ERC1155Base__MintToZeroAddress","type":"error"},{"inputs":[],"name":"ERC1155Base__NotOwnerOrApproved","type":"error"},{"inputs":[],"name":"ERC1155Base__SelfApproval","type":"error"},{"inputs":[],"name":"ERC1155Base__TransferExceedsBalance","type":"error"},{"inputs":[],"name":"ERC1155Base__TransferToZeroAddress","type":"error"},{"inputs":[],"name":"ERC165Base__InvalidInterfaceId","type":"error"},{"inputs":[],"name":"Ownable__NotOwner","type":"error"},{"inputs":[],"name":"Ownable__NotTransitiveOwner","type":"error"},{"inputs":[],"name":"Unapprovable","type":"error"},{"inputs":[],"name":"Untransferable","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","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":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"URI","type":"event"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"airdrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"burnBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_metadataUri","type":"string"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"bool","name":"","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI_","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]

608060405234801561001057600080fd5b50611e45806100206000396000f3fe608060405234801561001057600080fd5b50600436106101205760003560e01c80638da5cb5b116100ad578063e985e9c511610071578063e985e9c5146102bf578063f242432a146102d2578063f2fde38b146102e0578063f5298aca146102f3578063f62d18881461030657600080fd5b80638da5cb5b1461023257806395d89b4114610252578063a22cb4651461025a578063a496dedf1461026d578063bd85b0391461028057600080fd5b80632eb2c2d6116100f45780632eb2c2d6146101965780634e1273f4146101ab5780634f558e79146101cb57806355f804b31461020c5780636b20c4541461021f57600080fd5b8062fdd58e1461012557806301ffc9a71461014b57806306fdde031461016e5780630e89341c14610183575b600080fd5b6101386101333660046114ac565b610319565b6040519081526020015b60405180910390f35b61015e6101593660046114d6565b61032e565b6040519015158152602001610142565b61017661036f565b604051610142919061152b565b61017661019136600461155e565b61040e565b6101a96101a43660046116c5565b6105dd565b005b6101be6101b93660046117d1565b6105f6565b6040516101429190611870565b61015e6101d936600461155e565b60009081527fb8caebe71f1a0eacb8795f42f4a2773f5b3a61687beee75da335d708b1605dae6020526040902054151590565b6101a961021a366004611883565b610761565b6101a961022d3660046118cc565b6107a6565b61023a6107f9565b6040516001600160a01b039091168152602001610142565b610176610808565b6101a9610268366004611940565b610827565b6101a961027b36600461197c565b610840565b61013861028e36600461155e565b60009081527fb8caebe71f1a0eacb8795f42f4a2773f5b3a61687beee75da335d708b1605dae602052604090205490565b61015e6102cd3660046119ca565b6108cb565b6101a96101a43660046119fd565b6101a96102ee366004611a62565b610918565b6101a9610301366004611a7d565b61095a565b6101a9610314366004611883565b61099e565b60006103258383610b09565b90505b92915050565b6001600160e01b0319811660009081527ffc606c433378e3a7e0a6a531deac289b66caa1b4aa8554fd4ab2c6f1570f92d8602052604081205460ff16610328565b6060600080516020611db0833981519152805461038b90611ab0565b80601f01602080910402602001604051908101604052809291908181526020018280546103b790611ab0565b80156104045780601f106103d957610100808354040283529160200191610404565b820191906000526020600020905b8154815290600101906020018083116103e757829003601f168201915b5050505050905090565b60008181527f4281b61aefbe70b3d3f684b428efca5f33077bc240e76f2808f9177c307617f56020526040812080546060927f4281b61aefbe70b3d3f684b428efca5f33077bc240e76f2808f9177c307617f492909161046d90611ab0565b80601f016020809104026020016040519081016040528092919081815260200182805461049990611ab0565b80156104e65780601f106104bb576101008083540402835291602001916104e6565b820191906000526020600020905b8154815290600101906020018083116104c957829003601f168201915b5050505050905060008260000180546104fe90611ab0565b80601f016020809104026020016040519081016040528092919081815260200182805461052a90611ab0565b80156105775780601f1061054c57610100808354040283529160200191610577565b820191906000526020600020905b81548152906001019060200180831161055a57829003601f168201915b50505050509050805160000361058f57509392505050565b8151156105c25780826040516020016105a9929190611aea565b6040516020818303038152906040529350505050919050565b806105cc86610b67565b6040516020016105a9929190611aea565b60405163072b78c760e01b815260040160405180910390fd5b6060815183511461061a57604051633e7e0b6d60e11b815260040160405180910390fd5b8251600080516020611df08339815191529060009067ffffffffffffffff81111561064757610647611577565b604051908082528060200260200182016040528015610670578160200160208202803683370190505b50905060005b85518110156107585760006001600160a01b031686828151811061069c5761069c611b19565b60200260200101516001600160a01b0316036106cb5760405163db5d879760e01b815260040160405180910390fd5b8260008683815181106106e0576106e0611b19565b60200260200101518152602001908152602001600020600087838151811061070a5761070a611b19565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000205482828151811061074557610745611b19565b6020908102919091010152600101610676565b50949350505050565b610769610c70565b6001600160a01b0316336001600160a01b03161461079a57604051632f7a8ee160e01b815260040160405180910390fd5b6107a381610c9e565b50565b826001600160a01b0381163314806107c357506107c381336108cb565b6107e85760405162461bcd60e51b81526004016107df90611b2f565b60405180910390fd5b6107f3848484610cc9565b50505050565b6000610803610c70565b905090565b6060600080516020611db0833981519152600101805461038b90611ab0565b60405163595162dd60e01b815260040160405180910390fd5b610848610c70565b6001600160a01b0316336001600160a01b03161461087957604051632f7a8ee160e01b815260040160405180910390fd5b60005b83518110156107f3576108b984828151811061089a5761089a611b19565b6020026020010151848460405180602001604052806000815250610e83565b806108c381611b93565b91505061087c565b6001600160a01b0391821660009081527f1799cf914cb0cb442ca7c7ac709ee40d0cb89e87351dc08d517fbda27d50c68c6020908152604080832093909416825291909152205460ff1690565b610920610c70565b6001600160a01b0316336001600160a01b03161461095157604051632f7a8ee160e01b815260040160405180910390fd5b6107a381610f53565b826001600160a01b038116331480610977575061097781336108cb565b6109935760405162461bcd60e51b81526004016107df90611b2f565b6107f3848484610f5c565b600080516020611dd083398151915254610100900460ff166109d357600080516020611dd08339815191525460ff16156109d7565b303b155b610a5a5760405162461bcd60e51b815260206004820152604860248201527f547261636b61626c654275726e61626c65455243313135355f5f496e6974696160448201527f6c697a61626c653a20636f6e747261637420697320616c726561647920696e696064820152671d1a585b1a5e995960c21b608482015260a4016107df565b600080516020611dd083398151915254610100900460ff16158015610a9657600080516020611dd0833981519152805461ffff19166101011790555b610ae66040518060400160405280601281526020017129b8bab4b9b434a137bab732102a37b5b2b760711b8152506040518060400160405280600381526020016214d09560ea1b81525084610fa0565b8015610b0557600080516020611dd0833981519152805461ff00191690555b5050565b60006001600160a01b038316610b325760405163db5d879760e01b815260040160405180910390fd5b600080516020611df08339815191526000928352602090815260408084206001600160a01b0395909516845293905250205490565b606081600003610b8e5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610bb85780610ba281611b93565b9150610bb19050600a83611bc2565b9150610b92565b60008167ffffffffffffffff811115610bd357610bd3611577565b6040519080825280601f01601f191660200182016040528015610bfd576020820181803683370190505b5090505b8415610c6857610c12600183611bd6565b9150610c1f600a86611be9565b610c2a906030611bfd565b60f81b818381518110610c3f57610c3f611b19565b60200101906001600160f81b031916908160001a905350610c61600a86611bc2565b9450610c01565b949350505050565b7f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f671680460546001600160a01b031690565b7f4281b61aefbe70b3d3f684b428efca5f33077bc240e76f2808f9177c307617f4610b058282611c56565b6001600160a01b038316610cf05760405163baa75df760e01b815260040160405180910390fd5b8051825114610d1257604051633e7e0b6d60e11b815260040160405180910390fd5b610d3033846000858560405180602001604052806000815250610fe4565b600080516020611df083398151915260005b8351811015610e24576000848281518110610d5f57610d5f611b19565b602002602001015190508260008281526020019081526020016000206000876001600160a01b03166001600160a01b0316815260200190815260200160002054848381518110610db157610db1611b19565b60200260200101511115610dd857604051634190713d60e01b815260040160405180910390fd5b838281518110610dea57610dea611b19565b602090810291909101810151600092835284825260408084206001600160a01b038a16855290925291208054919091039055600101610d42565b5060006001600160a01b0316846001600160a01b0316336001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051610e75929190611d16565b60405180910390a450505050565b6001600160a01b038416610eaa576040516301c8efbf60e11b815260040160405180910390fd5b610ec933600086610eba876111b0565b610ec3876111b0565b86610fe4565b6000838152600080516020611df0833981519152602090815260408083206001600160a01b038816845290915281208054849290610f08908490611bfd565b909155505060408051848152602081018490526001600160a01b0386169160009133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f629101610e75565b6107a3816111fb565b826001600160a01b038116331480610f795750610f7981336108cb565b610f955760405162461bcd60e51b81526004016107df90611b2f565b6107f3848484611275565b600080516020611dd083398151915254610100900460ff16610fd45760405162461bcd60e51b81526004016107df90611d44565b610fdf838383611374565b505050565b6001600160a01b0385166110815760005b835181101561107f5782818151811061101057611010611b19565b602002602001015161102d600080516020611db083398151915290565b600201600086848151811061104457611044611b19565b6020026020010151815260200190815260200160002060008282546110699190611bfd565b90915550611078905081611b93565b9050610ff5565b505b6001600160a01b0384166111a85760005b83518110156111a65760008482815181106110af576110af611b19565b6020026020010151905060008483815181106110cd576110cd611b19565b6020026020010151905060006110ee600080516020611db083398151915290565b600084815260029190910160205260409020549050818110156111645760405162461bcd60e51b815260206004820152602860248201527f455243313135353a206275726e20616d6f756e74206578636565647320746f74604482015267616c537570706c7960c01b60648201526084016107df565b60009283527fb8caebe71f1a0eacb8795f42f4a2773f5b3a61687beee75da335d708b1605dae60205260409092209103905561119f81611b93565b9050611092565b505b505050505050565b604080516001808252818301909252606091600091906020808301908036833701905050905082816000815181106111ea576111ea611b19565b602090810291909101015292915050565b7f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046080546040516001600160a01b038481169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a380546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b03831661129c5760405163baa75df760e01b815260040160405180910390fd5b6112ca338460006112ac866111b0565b6112b5866111b0565b60405180602001604052806000815250610fe4565b6000828152600080516020611df0833981519152602090815260408083206001600160a01b0387168452918290529091205482111561131c57604051634190713d60e01b815260040160405180910390fd5b6001600160a01b03841660008181526020838152604080832080548790039055805187815291820186905291929133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f629101610e75565b600080516020611dd083398151915254610100900460ff166113a85760405162461bcd60e51b81526004016107df90611d44565b6113b181610c9e565b6113c36301ffc9a760e01b600161141a565b6113d5636cdb3d1360e11b600161141a565b600080516020611db08339815191526113ee8482611c56565b507fb8caebe71f1a0eacb8795f42f4a2773f5b3a61687beee75da335d708b1605dad6107f38382611c56565b6001600160e01b031980831690036114455760405163b0a19dd560e01b815260040160405180910390fd5b6001600160e01b03199190911660009081527ffc606c433378e3a7e0a6a531deac289b66caa1b4aa8554fd4ab2c6f1570f92d860205260409020805460ff1916911515919091179055565b80356001600160a01b03811681146114a757600080fd5b919050565b600080604083850312156114bf57600080fd5b6114c883611490565b946020939093013593505050565b6000602082840312156114e857600080fd5b81356001600160e01b03198116811461150057600080fd5b9392505050565b60005b8381101561152257818101518382015260200161150a565b50506000910152565b602081526000825180602084015261154a816040850160208701611507565b601f01601f19169190910160400192915050565b60006020828403121561157057600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156115b6576115b6611577565b604052919050565b600067ffffffffffffffff8211156115d8576115d8611577565b5060051b60200190565b600082601f8301126115f357600080fd5b81356020611608611603836115be565b61158d565b82815260059290921b8401810191818101908684111561162757600080fd5b8286015b84811015611642578035835291830191830161162b565b509695505050505050565b600067ffffffffffffffff83111561166757611667611577565b61167a601f8401601f191660200161158d565b905082815283838301111561168e57600080fd5b828260208301376000602084830101529392505050565b600082601f8301126116b657600080fd5b6103258383356020850161164d565b600080600080600060a086880312156116dd57600080fd5b6116e686611490565b94506116f460208701611490565b9350604086013567ffffffffffffffff8082111561171157600080fd5b61171d89838a016115e2565b9450606088013591508082111561173357600080fd5b61173f89838a016115e2565b9350608088013591508082111561175557600080fd5b50611762888289016116a5565b9150509295509295909350565b600082601f83011261178057600080fd5b81356020611790611603836115be565b82815260059290921b840181019181810190868411156117af57600080fd5b8286015b84811015611642576117c481611490565b83529183019183016117b3565b600080604083850312156117e457600080fd5b823567ffffffffffffffff808211156117fc57600080fd5b6118088683870161176f565b9350602085013591508082111561181e57600080fd5b5061182b858286016115e2565b9150509250929050565b600081518084526020808501945080840160005b8381101561186557815187529582019590820190600101611849565b509495945050505050565b6020815260006103256020830184611835565b60006020828403121561189557600080fd5b813567ffffffffffffffff8111156118ac57600080fd5b8201601f810184136118bd57600080fd5b610c688482356020840161164d565b6000806000606084860312156118e157600080fd5b6118ea84611490565b9250602084013567ffffffffffffffff8082111561190757600080fd5b611913878388016115e2565b9350604086013591508082111561192957600080fd5b50611936868287016115e2565b9150509250925092565b6000806040838503121561195357600080fd5b61195c83611490565b91506020830135801515811461197157600080fd5b809150509250929050565b60008060006060848603121561199157600080fd5b833567ffffffffffffffff8111156119a857600080fd5b6119b48682870161176f565b9660208601359650604090950135949350505050565b600080604083850312156119dd57600080fd5b6119e683611490565b91506119f460208401611490565b90509250929050565b600080600080600060a08688031215611a1557600080fd5b611a1e86611490565b9450611a2c60208701611490565b93506040860135925060608601359150608086013567ffffffffffffffff811115611a5657600080fd5b611762888289016116a5565b600060208284031215611a7457600080fd5b61032582611490565b600080600060608486031215611a9257600080fd5b611a9b84611490565b95602085013595506040909401359392505050565b600181811c90821680611ac457607f821691505b602082108103611ae457634e487b7160e01b600052602260045260246000fd5b50919050565b60008351611afc818460208801611507565b835190830190611b10818360208801611507565b01949350505050565b634e487b7160e01b600052603260045260246000fd5b6020808252602e908201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60408201526d195c881bdc88185c1c1c9bdd995960921b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b600060018201611ba557611ba5611b7d565b5060010190565b634e487b7160e01b600052601260045260246000fd5b600082611bd157611bd1611bac565b500490565b8181038181111561032857610328611b7d565b600082611bf857611bf8611bac565b500690565b8082018082111561032857610328611b7d565b601f821115610fdf57600081815260208120601f850160051c81016020861015611c375750805b601f850160051c820191505b818110156111a857828155600101611c43565b815167ffffffffffffffff811115611c7057611c70611577565b611c8481611c7e8454611ab0565b84611c10565b602080601f831160018114611cb95760008415611ca15750858301515b600019600386901b1c1916600185901b1785556111a8565b600085815260208120601f198616915b82811015611ce857888601518255948401946001909101908401611cc9565b5085821015611d065787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b604081526000611d296040830185611835565b8281036020840152611d3b8185611835565b95945050505050565b60208082526045908201527f547261636b61626c654275726e61626c65455243313135355f5f496e6974696160408201527f6c697a61626c653a20636f6e7472616374206973206e6f7420696e697469616c606082015264697a696e6760d81b608082015260a0019056feb8caebe71f1a0eacb8795f42f4a2773f5b3a61687beee75da335d708b1605dacabe45e00fd9799429b3ee180cead5a46837b656f37f50c8551eb3f017ce43ae71799cf914cb0cb442ca7c7ac709ee40d0cb89e87351dc08d517fbda27d50c68ba26469706673582212209af1451e9bb8dddb2b07963903a9a29301ab3d7fab9a69c780b2064c45d0286e64736f6c63430008110033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101205760003560e01c80638da5cb5b116100ad578063e985e9c511610071578063e985e9c5146102bf578063f242432a146102d2578063f2fde38b146102e0578063f5298aca146102f3578063f62d18881461030657600080fd5b80638da5cb5b1461023257806395d89b4114610252578063a22cb4651461025a578063a496dedf1461026d578063bd85b0391461028057600080fd5b80632eb2c2d6116100f45780632eb2c2d6146101965780634e1273f4146101ab5780634f558e79146101cb57806355f804b31461020c5780636b20c4541461021f57600080fd5b8062fdd58e1461012557806301ffc9a71461014b57806306fdde031461016e5780630e89341c14610183575b600080fd5b6101386101333660046114ac565b610319565b6040519081526020015b60405180910390f35b61015e6101593660046114d6565b61032e565b6040519015158152602001610142565b61017661036f565b604051610142919061152b565b61017661019136600461155e565b61040e565b6101a96101a43660046116c5565b6105dd565b005b6101be6101b93660046117d1565b6105f6565b6040516101429190611870565b61015e6101d936600461155e565b60009081527fb8caebe71f1a0eacb8795f42f4a2773f5b3a61687beee75da335d708b1605dae6020526040902054151590565b6101a961021a366004611883565b610761565b6101a961022d3660046118cc565b6107a6565b61023a6107f9565b6040516001600160a01b039091168152602001610142565b610176610808565b6101a9610268366004611940565b610827565b6101a961027b36600461197c565b610840565b61013861028e36600461155e565b60009081527fb8caebe71f1a0eacb8795f42f4a2773f5b3a61687beee75da335d708b1605dae602052604090205490565b61015e6102cd3660046119ca565b6108cb565b6101a96101a43660046119fd565b6101a96102ee366004611a62565b610918565b6101a9610301366004611a7d565b61095a565b6101a9610314366004611883565b61099e565b60006103258383610b09565b90505b92915050565b6001600160e01b0319811660009081527ffc606c433378e3a7e0a6a531deac289b66caa1b4aa8554fd4ab2c6f1570f92d8602052604081205460ff16610328565b6060600080516020611db0833981519152805461038b90611ab0565b80601f01602080910402602001604051908101604052809291908181526020018280546103b790611ab0565b80156104045780601f106103d957610100808354040283529160200191610404565b820191906000526020600020905b8154815290600101906020018083116103e757829003601f168201915b5050505050905090565b60008181527f4281b61aefbe70b3d3f684b428efca5f33077bc240e76f2808f9177c307617f56020526040812080546060927f4281b61aefbe70b3d3f684b428efca5f33077bc240e76f2808f9177c307617f492909161046d90611ab0565b80601f016020809104026020016040519081016040528092919081815260200182805461049990611ab0565b80156104e65780601f106104bb576101008083540402835291602001916104e6565b820191906000526020600020905b8154815290600101906020018083116104c957829003601f168201915b5050505050905060008260000180546104fe90611ab0565b80601f016020809104026020016040519081016040528092919081815260200182805461052a90611ab0565b80156105775780601f1061054c57610100808354040283529160200191610577565b820191906000526020600020905b81548152906001019060200180831161055a57829003601f168201915b50505050509050805160000361058f57509392505050565b8151156105c25780826040516020016105a9929190611aea565b6040516020818303038152906040529350505050919050565b806105cc86610b67565b6040516020016105a9929190611aea565b60405163072b78c760e01b815260040160405180910390fd5b6060815183511461061a57604051633e7e0b6d60e11b815260040160405180910390fd5b8251600080516020611df08339815191529060009067ffffffffffffffff81111561064757610647611577565b604051908082528060200260200182016040528015610670578160200160208202803683370190505b50905060005b85518110156107585760006001600160a01b031686828151811061069c5761069c611b19565b60200260200101516001600160a01b0316036106cb5760405163db5d879760e01b815260040160405180910390fd5b8260008683815181106106e0576106e0611b19565b60200260200101518152602001908152602001600020600087838151811061070a5761070a611b19565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000205482828151811061074557610745611b19565b6020908102919091010152600101610676565b50949350505050565b610769610c70565b6001600160a01b0316336001600160a01b03161461079a57604051632f7a8ee160e01b815260040160405180910390fd5b6107a381610c9e565b50565b826001600160a01b0381163314806107c357506107c381336108cb565b6107e85760405162461bcd60e51b81526004016107df90611b2f565b60405180910390fd5b6107f3848484610cc9565b50505050565b6000610803610c70565b905090565b6060600080516020611db0833981519152600101805461038b90611ab0565b60405163595162dd60e01b815260040160405180910390fd5b610848610c70565b6001600160a01b0316336001600160a01b03161461087957604051632f7a8ee160e01b815260040160405180910390fd5b60005b83518110156107f3576108b984828151811061089a5761089a611b19565b6020026020010151848460405180602001604052806000815250610e83565b806108c381611b93565b91505061087c565b6001600160a01b0391821660009081527f1799cf914cb0cb442ca7c7ac709ee40d0cb89e87351dc08d517fbda27d50c68c6020908152604080832093909416825291909152205460ff1690565b610920610c70565b6001600160a01b0316336001600160a01b03161461095157604051632f7a8ee160e01b815260040160405180910390fd5b6107a381610f53565b826001600160a01b038116331480610977575061097781336108cb565b6109935760405162461bcd60e51b81526004016107df90611b2f565b6107f3848484610f5c565b600080516020611dd083398151915254610100900460ff166109d357600080516020611dd08339815191525460ff16156109d7565b303b155b610a5a5760405162461bcd60e51b815260206004820152604860248201527f547261636b61626c654275726e61626c65455243313135355f5f496e6974696160448201527f6c697a61626c653a20636f6e747261637420697320616c726561647920696e696064820152671d1a585b1a5e995960c21b608482015260a4016107df565b600080516020611dd083398151915254610100900460ff16158015610a9657600080516020611dd0833981519152805461ffff19166101011790555b610ae66040518060400160405280601281526020017129b8bab4b9b434a137bab732102a37b5b2b760711b8152506040518060400160405280600381526020016214d09560ea1b81525084610fa0565b8015610b0557600080516020611dd0833981519152805461ff00191690555b5050565b60006001600160a01b038316610b325760405163db5d879760e01b815260040160405180910390fd5b600080516020611df08339815191526000928352602090815260408084206001600160a01b0395909516845293905250205490565b606081600003610b8e5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610bb85780610ba281611b93565b9150610bb19050600a83611bc2565b9150610b92565b60008167ffffffffffffffff811115610bd357610bd3611577565b6040519080825280601f01601f191660200182016040528015610bfd576020820181803683370190505b5090505b8415610c6857610c12600183611bd6565b9150610c1f600a86611be9565b610c2a906030611bfd565b60f81b818381518110610c3f57610c3f611b19565b60200101906001600160f81b031916908160001a905350610c61600a86611bc2565b9450610c01565b949350505050565b7f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f671680460546001600160a01b031690565b7f4281b61aefbe70b3d3f684b428efca5f33077bc240e76f2808f9177c307617f4610b058282611c56565b6001600160a01b038316610cf05760405163baa75df760e01b815260040160405180910390fd5b8051825114610d1257604051633e7e0b6d60e11b815260040160405180910390fd5b610d3033846000858560405180602001604052806000815250610fe4565b600080516020611df083398151915260005b8351811015610e24576000848281518110610d5f57610d5f611b19565b602002602001015190508260008281526020019081526020016000206000876001600160a01b03166001600160a01b0316815260200190815260200160002054848381518110610db157610db1611b19565b60200260200101511115610dd857604051634190713d60e01b815260040160405180910390fd5b838281518110610dea57610dea611b19565b602090810291909101810151600092835284825260408084206001600160a01b038a16855290925291208054919091039055600101610d42565b5060006001600160a01b0316846001600160a01b0316336001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051610e75929190611d16565b60405180910390a450505050565b6001600160a01b038416610eaa576040516301c8efbf60e11b815260040160405180910390fd5b610ec933600086610eba876111b0565b610ec3876111b0565b86610fe4565b6000838152600080516020611df0833981519152602090815260408083206001600160a01b038816845290915281208054849290610f08908490611bfd565b909155505060408051848152602081018490526001600160a01b0386169160009133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f629101610e75565b6107a3816111fb565b826001600160a01b038116331480610f795750610f7981336108cb565b610f955760405162461bcd60e51b81526004016107df90611b2f565b6107f3848484611275565b600080516020611dd083398151915254610100900460ff16610fd45760405162461bcd60e51b81526004016107df90611d44565b610fdf838383611374565b505050565b6001600160a01b0385166110815760005b835181101561107f5782818151811061101057611010611b19565b602002602001015161102d600080516020611db083398151915290565b600201600086848151811061104457611044611b19565b6020026020010151815260200190815260200160002060008282546110699190611bfd565b90915550611078905081611b93565b9050610ff5565b505b6001600160a01b0384166111a85760005b83518110156111a65760008482815181106110af576110af611b19565b6020026020010151905060008483815181106110cd576110cd611b19565b6020026020010151905060006110ee600080516020611db083398151915290565b600084815260029190910160205260409020549050818110156111645760405162461bcd60e51b815260206004820152602860248201527f455243313135353a206275726e20616d6f756e74206578636565647320746f74604482015267616c537570706c7960c01b60648201526084016107df565b60009283527fb8caebe71f1a0eacb8795f42f4a2773f5b3a61687beee75da335d708b1605dae60205260409092209103905561119f81611b93565b9050611092565b505b505050505050565b604080516001808252818301909252606091600091906020808301908036833701905050905082816000815181106111ea576111ea611b19565b602090810291909101015292915050565b7f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046080546040516001600160a01b038481169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a380546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b03831661129c5760405163baa75df760e01b815260040160405180910390fd5b6112ca338460006112ac866111b0565b6112b5866111b0565b60405180602001604052806000815250610fe4565b6000828152600080516020611df0833981519152602090815260408083206001600160a01b0387168452918290529091205482111561131c57604051634190713d60e01b815260040160405180910390fd5b6001600160a01b03841660008181526020838152604080832080548790039055805187815291820186905291929133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f629101610e75565b600080516020611dd083398151915254610100900460ff166113a85760405162461bcd60e51b81526004016107df90611d44565b6113b181610c9e565b6113c36301ffc9a760e01b600161141a565b6113d5636cdb3d1360e11b600161141a565b600080516020611db08339815191526113ee8482611c56565b507fb8caebe71f1a0eacb8795f42f4a2773f5b3a61687beee75da335d708b1605dad6107f38382611c56565b6001600160e01b031980831690036114455760405163b0a19dd560e01b815260040160405180910390fd5b6001600160e01b03199190911660009081527ffc606c433378e3a7e0a6a531deac289b66caa1b4aa8554fd4ab2c6f1570f92d860205260409020805460ff1916911515919091179055565b80356001600160a01b03811681146114a757600080fd5b919050565b600080604083850312156114bf57600080fd5b6114c883611490565b946020939093013593505050565b6000602082840312156114e857600080fd5b81356001600160e01b03198116811461150057600080fd5b9392505050565b60005b8381101561152257818101518382015260200161150a565b50506000910152565b602081526000825180602084015261154a816040850160208701611507565b601f01601f19169190910160400192915050565b60006020828403121561157057600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156115b6576115b6611577565b604052919050565b600067ffffffffffffffff8211156115d8576115d8611577565b5060051b60200190565b600082601f8301126115f357600080fd5b81356020611608611603836115be565b61158d565b82815260059290921b8401810191818101908684111561162757600080fd5b8286015b84811015611642578035835291830191830161162b565b509695505050505050565b600067ffffffffffffffff83111561166757611667611577565b61167a601f8401601f191660200161158d565b905082815283838301111561168e57600080fd5b828260208301376000602084830101529392505050565b600082601f8301126116b657600080fd5b6103258383356020850161164d565b600080600080600060a086880312156116dd57600080fd5b6116e686611490565b94506116f460208701611490565b9350604086013567ffffffffffffffff8082111561171157600080fd5b61171d89838a016115e2565b9450606088013591508082111561173357600080fd5b61173f89838a016115e2565b9350608088013591508082111561175557600080fd5b50611762888289016116a5565b9150509295509295909350565b600082601f83011261178057600080fd5b81356020611790611603836115be565b82815260059290921b840181019181810190868411156117af57600080fd5b8286015b84811015611642576117c481611490565b83529183019183016117b3565b600080604083850312156117e457600080fd5b823567ffffffffffffffff808211156117fc57600080fd5b6118088683870161176f565b9350602085013591508082111561181e57600080fd5b5061182b858286016115e2565b9150509250929050565b600081518084526020808501945080840160005b8381101561186557815187529582019590820190600101611849565b509495945050505050565b6020815260006103256020830184611835565b60006020828403121561189557600080fd5b813567ffffffffffffffff8111156118ac57600080fd5b8201601f810184136118bd57600080fd5b610c688482356020840161164d565b6000806000606084860312156118e157600080fd5b6118ea84611490565b9250602084013567ffffffffffffffff8082111561190757600080fd5b611913878388016115e2565b9350604086013591508082111561192957600080fd5b50611936868287016115e2565b9150509250925092565b6000806040838503121561195357600080fd5b61195c83611490565b91506020830135801515811461197157600080fd5b809150509250929050565b60008060006060848603121561199157600080fd5b833567ffffffffffffffff8111156119a857600080fd5b6119b48682870161176f565b9660208601359650604090950135949350505050565b600080604083850312156119dd57600080fd5b6119e683611490565b91506119f460208401611490565b90509250929050565b600080600080600060a08688031215611a1557600080fd5b611a1e86611490565b9450611a2c60208701611490565b93506040860135925060608601359150608086013567ffffffffffffffff811115611a5657600080fd5b611762888289016116a5565b600060208284031215611a7457600080fd5b61032582611490565b600080600060608486031215611a9257600080fd5b611a9b84611490565b95602085013595506040909401359392505050565b600181811c90821680611ac457607f821691505b602082108103611ae457634e487b7160e01b600052602260045260246000fd5b50919050565b60008351611afc818460208801611507565b835190830190611b10818360208801611507565b01949350505050565b634e487b7160e01b600052603260045260246000fd5b6020808252602e908201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60408201526d195c881bdc88185c1c1c9bdd995960921b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b600060018201611ba557611ba5611b7d565b5060010190565b634e487b7160e01b600052601260045260246000fd5b600082611bd157611bd1611bac565b500490565b8181038181111561032857610328611b7d565b600082611bf857611bf8611bac565b500690565b8082018082111561032857610328611b7d565b601f821115610fdf57600081815260208120601f850160051c81016020861015611c375750805b601f850160051c820191505b818110156111a857828155600101611c43565b815167ffffffffffffffff811115611c7057611c70611577565b611c8481611c7e8454611ab0565b84611c10565b602080601f831160018114611cb95760008415611ca15750858301515b600019600386901b1c1916600185901b1785556111a8565b600085815260208120601f198616915b82811015611ce857888601518255948401946001909101908401611cc9565b5085821015611d065787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b604081526000611d296040830185611835565b8281036020840152611d3b8185611835565b95945050505050565b60208082526045908201527f547261636b61626c654275726e61626c65455243313135355f5f496e6974696160408201527f6c697a61626c653a20636f6e7472616374206973206e6f7420696e697469616c606082015264697a696e6760d81b608082015260a0019056feb8caebe71f1a0eacb8795f42f4a2773f5b3a61687beee75da335d708b1605dacabe45e00fd9799429b3ee180cead5a46837b656f37f50c8551eb3f017ce43ae71799cf914cb0cb442ca7c7ac709ee40d0cb89e87351dc08d517fbda27d50c68ba26469706673582212209af1451e9bb8dddb2b07963903a9a29301ab3d7fab9a69c780b2064c45d0286e64736f6c63430008110033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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

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