ETH Price: $3,280.77 (-1.49%)

Contract

0xfFFffffFB9059A7285849baFddf324e2c308c164
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
0xba139990c047a4f4eeac86acdf958e7c930f13c5b1ddcb58fe0888fc9b422ba3 Mint(pending)2024-12-22 20:29:5010 hrs ago1734899390IN
mint.fun: Fundrop Stickers
0 ETH(Pending)(Pending)
0x1b4e3a6b6c7133ed5394095f5c087a06ad0f0be9077a2111efae1b6bcae14a9d Mint(pending)2024-12-22 15:33:4115 hrs ago1734881621IN
mint.fun: Fundrop Stickers
0 ETH(Pending)(Pending)
0x304a27445fffaaf82a33d614a12f8c6fbdad8030b43bf11103c303df9174f12e Mint(pending)2024-12-22 13:32:5417 hrs ago1734874374IN
mint.fun: Fundrop Stickers
0 ETH(Pending)(Pending)
0x40ab9781b66c4f47ea9785005a32d02351ca74e7c78cb57bfb107f03b64f19f1 Mint(pending)2024-12-22 10:50:1820 hrs ago1734864618IN
mint.fun: Fundrop Stickers
0 ETH(Pending)(Pending)
0x3b71f54c82f768b8463a7d28580926ad0c66e1a6df5ba602cf7b3dd699830a7b Mint(pending)2024-12-22 8:33:3022 hrs ago1734856410IN
mint.fun: Fundrop Stickers
0 ETH(Pending)(Pending)
0x335cc43a47c8c1acfb9f04df82d1896c37e51109f5fb2e42b68c0428f7cb87b3 Mint(pending)2024-12-22 8:24:1922 hrs ago1734855859IN
mint.fun: Fundrop Stickers
0 ETH(Pending)(Pending)
0x9382b2a84e79a009236421819a9224f4585186cd38ddbf62fe74f48fc338f705 Mint(pending)2024-12-22 7:20:5823 hrs ago1734852058IN
mint.fun: Fundrop Stickers
0 ETH(Pending)(Pending)
0x648d246b40a1aa17393e570520c9d446a4ec380708de55c9b04c2b1e02cd4aad Mint(pending)2024-12-22 4:55:1726 hrs ago1734843317IN
mint.fun: Fundrop Stickers
0 ETH(Pending)(Pending)
0x957d77b90d9e165b67f60649ec7a2a0a1a4b93f8e46a07ea1c25bab38846917b Mint(pending)2024-12-22 2:25:2828 hrs ago1734834328IN
mint.fun: Fundrop Stickers
0 ETH(Pending)(Pending)
0x07f5ef621a41e04886eaf53a6521d4531dfe5acbd2eda2579ffe6c6823c847f8 Mint(pending)2024-12-15 1:27:038 days ago1734226023IN
mint.fun: Fundrop Stickers
0 ETH(Pending)(Pending)
Set Approval For...214602972024-12-22 20:03:1111 hrs ago1734897791IN
mint.fun: Fundrop Stickers
0 ETH0.000204716.81106481
Set Approval For...214570202024-12-22 9:03:3522 hrs ago1734858215IN
mint.fun: Fundrop Stickers
0 ETH0.000217194.72263626
Set Approval For...214521642024-12-21 16:45:2338 hrs ago1734799523IN
mint.fun: Fundrop Stickers
0 ETH0.000417939.08725409
Set Approval For...214136162024-12-16 7:34:476 days ago1734334487IN
mint.fun: Fundrop Stickers
0 ETH0.000308326.69353337
Set Approval For...214064542024-12-15 7:33:237 days ago1734248003IN
mint.fun: Fundrop Stickers
0 ETH0.000152256.30426114
Set Approval For...214023152024-12-14 17:42:478 days ago1734198167IN
mint.fun: Fundrop Stickers
0 ETH0.0005428611.80370437
Set Approval For...213858212024-12-12 10:26:4710 days ago1733999207IN
mint.fun: Fundrop Stickers
0 ETH0.0007558116.4040213
Set Approval For...213833432024-12-12 2:08:4711 days ago1733969327IN
mint.fun: Fundrop Stickers
0 ETH0.000558312.11739674
Set Approval For...213643952024-12-09 10:37:3513 days ago1733740655IN
mint.fun: Fundrop Stickers
0 ETH0.0005070411.02485427
Set Approval For...213621722024-12-09 3:11:5914 days ago1733713919IN
mint.fun: Fundrop Stickers
0 ETH0.000441179.57768911
Set Approval For...213558642024-12-08 6:04:5915 days ago1733637899IN
mint.fun: Fundrop Stickers
0 ETH0.000401898.72491858
Set Approval For...213487282024-12-07 6:08:2316 days ago1733551703IN
mint.fun: Fundrop Stickers
0 ETH0.0006695714.55875504
Set Approval For...213027312024-11-30 19:58:3522 days ago1732996715IN
mint.fun: Fundrop Stickers
0 ETH0.0006353413.8144904
Set Approval For...212998872024-11-30 10:26:1122 days ago1732962371IN
mint.fun: Fundrop Stickers
0 ETH0.000193828.04938793
Set Approval For...212922872024-11-29 8:54:1123 days ago1732870451IN
mint.fun: Fundrop Stickers
0 ETH0.00038628.38208757
View all transactions

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Block
From
To
179329472023-08-17 7:08:11494 days ago1692256091  Contract Creation0 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Stickers

Compiler Version
v0.8.20+commit.a1b79de6

Optimization Enabled:
Yes with 250000 runs

Other Settings:
paris EvmVersion
File 1 of 8 : Stickers.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.19;

import {ECDSA} from "solady/utils/ECDSA.sol";
import {Ownable} from "solady/auth/Ownable.sol";
import {ERC1155} from "solmate/tokens/ERC1155.sol";

import {IERC165} from "openzeppelin/utils/introspection/IERC165.sol";
import {IERC1155} from "openzeppelin/token/ERC1155/IERC1155.sol";
import "fundrop/IMetadataRenderer.sol";
import "fundrop/IERC4906.sol";

contract Stickers is ERC1155, Ownable {
    address public signer;
    address public metadataRenderer;
    uint256 public mintEnd;
    mapping(bytes32 => bool) _hasMinted;

    error InvalidSignature();
    error MintClosed();
    error MintedAlready();

    constructor() {
        _initializeOwner(tx.origin);
    }

    function name() public view virtual returns (string memory) {
        return "!fundrop Stickers";
    }

    function _packRecipientAndRound(address _address, uint16 _round) internal pure returns (bytes32) {
        return (bytes32(uint256(uint160(_address))) << 96) | bytes32(uint256(_round));
    }

    function mint(uint256[] calldata tokens, uint256[] calldata amounts, uint16 round, bytes calldata signature)
        public
        payable
    {
        bytes32 packedRecipientAndRound = _packRecipientAndRound(msg.sender, round);
        if (block.timestamp > mintEnd) revert MintClosed();
        if (_hasMinted[packedRecipientAndRound]) revert MintedAlready();
        address recovered =
            ECDSA.tryRecoverCalldata(keccak256(abi.encodePacked(msg.sender, round, tokens, amounts)), signature);
        if (recovered != signer) revert InvalidSignature();
        _hasMinted[packedRecipientAndRound] = true;
        _batchMint(msg.sender, tokens, amounts, "");
    }

    function adminMint(address to, uint256[] calldata tokens, uint256[] calldata amounts) public onlyOwner {
        _batchMint(to, tokens, amounts, "");
    }

    function uri(uint256 id) public view override returns (string memory) {
        return IMetadataRenderer(metadataRenderer).tokenURI(id);
    }

    // Admin functions

    function setMetadataRenderer(address _metadataRenderer) public onlyOwner {
        metadataRenderer = _metadataRenderer;
    }

    function setSigner(address _signer) public onlyOwner {
        signer = _signer;
    }

    function setMintEnd(uint256 _mintEnd) public onlyOwner {
        mintEnd = _mintEnd;
    }

    function supportsInterface(bytes4 interfaceId) public pure virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId || interfaceId == type(IERC1155).interfaceId
            || interfaceId == type(IERC4906).interfaceId;
    }
}

File 2 of 8 : ECDSA.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Gas optimized ECDSA wrapper.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ECDSA.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/ECDSA.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/ECDSA.sol)
library ECDSA {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                        CUSTOM ERRORS                       */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The signature is invalid.
    error InvalidSignature();

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                         CONSTANTS                          */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The number which `s` must not exceed in order for
    /// the signature to be non-malleable.
    bytes32 private constant _MALLEABILITY_THRESHOLD =
        0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                    RECOVERY OPERATIONS                     */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    // Note: as of Solady version 0.0.68, these functions will
    // revert upon recovery failure for more safety by default.

    /// @dev Recovers the signer's address from a message digest `hash`,
    /// and the `signature`.
    ///
    /// This function does NOT accept EIP-2098 short form signatures.
    /// Use `recover(bytes32 hash, bytes32 r, bytes32 vs)` for EIP-2098
    /// short form signatures instead.
    function recover(bytes32 hash, bytes memory signature) internal view returns (address result) {
        /// @solidity memory-safe-assembly
        assembly {
            // Copy the free memory pointer so that we can restore it later.
            let m := mload(0x40)
            // Copy `r` and `s`.
            mstore(0x40, mload(add(signature, 0x20))) // `r`.
            let s := mload(add(signature, 0x40))
            mstore(0x60, s)
            // Store the `hash` in the scratch space.
            mstore(0x00, hash)
            // Compute `v` and store it in the scratch space.
            mstore(0x20, byte(0, mload(add(signature, 0x60))))
            pop(
                staticcall(
                    gas(), // Amount of gas left for the transaction.
                    and(
                        // If the signature is exactly 65 bytes in length.
                        eq(mload(signature), 65),
                        // If `s` in lower half order, such that the signature is not malleable.
                        lt(s, add(_MALLEABILITY_THRESHOLD, 1))
                    ), // Address of `ecrecover`.
                    0x00, // Start of input.
                    0x80, // Size of input.
                    0x00, // Start of output.
                    0x20 // Size of output.
                )
            )
            result := mload(0x00)
            // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.
            if iszero(returndatasize()) {
                // Store the function selector of `InvalidSignature()`.
                mstore(0x00, 0x8baa579f)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }
            // Restore the zero slot.
            mstore(0x60, 0)
            // Restore the free memory pointer.
            mstore(0x40, m)
        }
    }

    /// @dev Recovers the signer's address from a message digest `hash`,
    /// and the `signature`.
    ///
    /// This function does NOT accept EIP-2098 short form signatures.
    /// Use `recover(bytes32 hash, bytes32 r, bytes32 vs)` for EIP-2098
    /// short form signatures instead.
    function recoverCalldata(bytes32 hash, bytes calldata signature)
        internal
        view
        returns (address result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            // Copy the free memory pointer so that we can restore it later.
            let m := mload(0x40)
            // Directly copy `r` and `s` from the calldata.
            calldatacopy(0x40, signature.offset, 0x40)
            // Store the `hash` in the scratch space.
            mstore(0x00, hash)
            // Compute `v` and store it in the scratch space.
            mstore(0x20, byte(0, calldataload(add(signature.offset, 0x40))))
            pop(
                staticcall(
                    gas(), // Amount of gas left for the transaction.
                    and(
                        // If the signature is exactly 65 bytes in length.
                        eq(signature.length, 65),
                        // If `s` in lower half order, such that the signature is not malleable.
                        lt(mload(0x60), add(_MALLEABILITY_THRESHOLD, 1))
                    ), // Address of `ecrecover`.
                    0x00, // Start of input.
                    0x80, // Size of input.
                    0x00, // Start of output.
                    0x20 // Size of output.
                )
            )
            result := mload(0x00)
            // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.
            if iszero(returndatasize()) {
                // Store the function selector of `InvalidSignature()`.
                mstore(0x00, 0x8baa579f)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }
            // Restore the zero slot.
            mstore(0x60, 0)
            // Restore the free memory pointer.
            mstore(0x40, m)
        }
    }

    /// @dev Recovers the signer's address from a message digest `hash`,
    /// and the EIP-2098 short form signature defined by `r` and `vs`.
    ///
    /// This function only accepts EIP-2098 short form signatures.
    /// See: https://eips.ethereum.org/EIPS/eip-2098
    ///
    /// To be honest, I do not recommend using EIP-2098 signatures
    /// for simplicity, performance, and security reasons. Most if not
    /// all clients support traditional non EIP-2098 signatures by default.
    /// As such, this method is intentionally not fully inlined.
    /// It is merely included for completeness.
    function recover(bytes32 hash, bytes32 r, bytes32 vs) internal view returns (address result) {
        uint8 v;
        bytes32 s;
        /// @solidity memory-safe-assembly
        assembly {
            s := shr(1, shl(1, vs))
            v := add(shr(255, vs), 27)
        }
        result = recover(hash, v, r, s);
    }

    /// @dev Recovers the signer's address from a message digest `hash`,
    /// and the signature defined by `v`, `r`, `s`.
    function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s)
        internal
        view
        returns (address result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            // Copy the free memory pointer so that we can restore it later.
            let m := mload(0x40)
            mstore(0x00, hash)
            mstore(0x20, and(v, 0xff))
            mstore(0x40, r)
            mstore(0x60, s)
            pop(
                staticcall(
                    gas(), // Amount of gas left for the transaction.
                    // If `s` in lower half order, such that the signature is not malleable.
                    lt(s, add(_MALLEABILITY_THRESHOLD, 1)), // Address of `ecrecover`.
                    0x00, // Start of input.
                    0x80, // Size of input.
                    0x00, // Start of output.
                    0x20 // Size of output.
                )
            )
            result := mload(0x00)
            // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.
            if iszero(returndatasize()) {
                // Store the function selector of `InvalidSignature()`.
                mstore(0x00, 0x8baa579f)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }
            // Restore the zero slot.
            mstore(0x60, 0)
            // Restore the free memory pointer.
            mstore(0x40, m)
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                   TRY-RECOVER OPERATIONS                   */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    // WARNING!
    // These functions will NOT revert upon recovery failure.
    // Instead, they will return the zero address upon recovery failure.
    // It is critical that the returned address is NEVER compared against
    // a zero address (e.g. an uninitialized address variable).

    /// @dev Recovers the signer's address from a message digest `hash`,
    /// and the `signature`.
    ///
    /// This function does NOT accept EIP-2098 short form signatures.
    /// Use `recover(bytes32 hash, bytes32 r, bytes32 vs)` for EIP-2098
    /// short form signatures instead.
    function tryRecover(bytes32 hash, bytes memory signature)
        internal
        view
        returns (address result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            if iszero(xor(mload(signature), 65)) {
                // Copy the free memory pointer so that we can restore it later.
                let m := mload(0x40)
                // Copy `r` and `s`.
                mstore(0x40, mload(add(signature, 0x20))) // `r`.
                let s := mload(add(signature, 0x40))
                mstore(0x60, s)
                // If `s` in lower half order, such that the signature is not malleable.
                if iszero(gt(s, _MALLEABILITY_THRESHOLD)) {
                    // Store the `hash` in the scratch space.
                    mstore(0x00, hash)
                    // Compute `v` and store it in the scratch space.
                    mstore(0x20, byte(0, mload(add(signature, 0x60))))
                    pop(
                        staticcall(
                            gas(), // Amount of gas left for the transaction.
                            0x01, // Address of `ecrecover`.
                            0x00, // Start of input.
                            0x80, // Size of input.
                            0x40, // Start of output.
                            0x20 // Size of output.
                        )
                    )
                    // Restore the zero slot.
                    mstore(0x60, 0)
                    // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.
                    result := mload(xor(0x60, returndatasize()))
                }
                // Restore the free memory pointer.
                mstore(0x40, m)
            }
        }
    }

    /// @dev Recovers the signer's address from a message digest `hash`,
    /// and the `signature`.
    ///
    /// This function does NOT accept EIP-2098 short form signatures.
    /// Use `recover(bytes32 hash, bytes32 r, bytes32 vs)` for EIP-2098
    /// short form signatures instead.
    function tryRecoverCalldata(bytes32 hash, bytes calldata signature)
        internal
        view
        returns (address result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            if iszero(xor(signature.length, 65)) {
                // Copy the free memory pointer so that we can restore it later.
                let m := mload(0x40)
                // Directly copy `r` and `s` from the calldata.
                calldatacopy(0x40, signature.offset, 0x40)
                // If `s` in lower half order, such that the signature is not malleable.
                if iszero(gt(mload(0x60), _MALLEABILITY_THRESHOLD)) {
                    // Store the `hash` in the scratch space.
                    mstore(0x00, hash)
                    // Compute `v` and store it in the scratch space.
                    mstore(0x20, byte(0, calldataload(add(signature.offset, 0x40))))
                    pop(
                        staticcall(
                            gas(), // Amount of gas left for the transaction.
                            0x01, // Address of `ecrecover`.
                            0x00, // Start of input.
                            0x80, // Size of input.
                            0x40, // Start of output.
                            0x20 // Size of output.
                        )
                    )
                    // Restore the zero slot.
                    mstore(0x60, 0)
                    // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.
                    result := mload(xor(0x60, returndatasize()))
                }
                // Restore the free memory pointer.
                mstore(0x40, m)
            }
        }
    }

    /// @dev Recovers the signer's address from a message digest `hash`,
    /// and the EIP-2098 short form signature defined by `r` and `vs`.
    ///
    /// This function only accepts EIP-2098 short form signatures.
    /// See: https://eips.ethereum.org/EIPS/eip-2098
    ///
    /// To be honest, I do not recommend using EIP-2098 signatures
    /// for simplicity, performance, and security reasons. Most if not
    /// all clients support traditional non EIP-2098 signatures by default.
    /// As such, this method is intentionally not fully inlined.
    /// It is merely included for completeness.
    function tryRecover(bytes32 hash, bytes32 r, bytes32 vs)
        internal
        view
        returns (address result)
    {
        uint8 v;
        bytes32 s;
        /// @solidity memory-safe-assembly
        assembly {
            s := shr(1, shl(1, vs))
            v := add(shr(255, vs), 27)
        }
        result = tryRecover(hash, v, r, s);
    }

    /// @dev Recovers the signer's address from a message digest `hash`,
    /// and the signature defined by `v`, `r`, `s`.
    function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s)
        internal
        view
        returns (address result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            // Copy the free memory pointer so that we can restore it later.
            let m := mload(0x40)
            // If `s` in lower half order, such that the signature is not malleable.
            if iszero(gt(s, _MALLEABILITY_THRESHOLD)) {
                // Store the `hash`, `v`, `r`, `s` in the scratch space.
                mstore(0x00, hash)
                mstore(0x20, and(v, 0xff))
                mstore(0x40, r)
                mstore(0x60, s)
                pop(
                    staticcall(
                        gas(), // Amount of gas left for the transaction.
                        0x01, // Address of `ecrecover`.
                        0x00, // Start of input.
                        0x80, // Size of input.
                        0x40, // Start of output.
                        0x20 // Size of output.
                    )
                )
                // Restore the zero slot.
                mstore(0x60, 0)
                // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.
                result := mload(xor(0x60, returndatasize()))
            }
            // Restore the free memory pointer.
            mstore(0x40, m)
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                     HASHING OPERATIONS                     */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns an Ethereum Signed Message, created from a `hash`.
    /// This produces a hash corresponding to the one signed with the
    /// [`eth_sign`](https://eth.wiki/json-rpc/API#eth_sign)
    /// JSON-RPC method as part of EIP-191.
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            // Store into scratch space for keccak256.
            mstore(0x20, hash)
            mstore(0x00, "\x00\x00\x00\x00\x19Ethereum Signed Message:\n32")
            // 0x40 - 0x04 = 0x3c
            result := keccak256(0x04, 0x3c)
        }
    }

    /// @dev Returns an Ethereum Signed Message, created from `s`.
    /// This produces a hash corresponding to the one signed with the
    /// [`eth_sign`](https://eth.wiki/json-rpc/API#eth_sign)
    /// JSON-RPC method as part of EIP-191.
    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32 result) {
        assembly {
            // The length of "\x19Ethereum Signed Message:\n" is 26 bytes (i.e. 0x1a).
            // If we reserve 2 words, we'll have 64 - 26 = 38 bytes to store the
            // ASCII decimal representation of the length of `s` up to about 2 ** 126.

            // Instead of allocating, we temporarily copy the 64 bytes before the
            // start of `s` data to some variables.
            let m := mload(sub(s, 0x20))
            // The length of `s` is in bytes.
            let sLength := mload(s)
            let ptr := add(s, 0x20)
            let w := not(0)
            // `end` marks the end of the memory which we will compute the keccak256 of.
            let end := add(ptr, sLength)
            // Convert the length of the bytes to ASCII decimal representation
            // and store it into the memory.
            for { let temp := sLength } 1 {} {
                ptr := add(ptr, w) // `sub(ptr, 1)`.
                mstore8(ptr, add(48, mod(temp, 10)))
                temp := div(temp, 10)
                if iszero(temp) { break }
            }
            // Copy the header over to the memory.
            mstore(sub(ptr, 0x20), "\x00\x00\x00\x00\x00\x00\x19Ethereum Signed Message:\n")
            // Compute the keccak256 of the memory.
            result := keccak256(sub(ptr, 0x1a), sub(end, sub(ptr, 0x1a)))
            // Restore the previous memory.
            mstore(s, sLength)
            mstore(sub(s, 0x20), m)
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                   EMPTY CALLDATA HELPERS                   */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns an empty calldata bytes.
    function emptySignature() internal pure returns (bytes calldata signature) {
        /// @solidity memory-safe-assembly
        assembly {
            signature.length := 0
        }
    }
}

File 3 of 8 : Ownable.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Simple single owner authorization mixin.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/auth/Ownable.sol)
/// @dev While the ownable portion follows [EIP-173](https://eips.ethereum.org/EIPS/eip-173)
/// for compatibility, the nomenclature for the 2-step ownership handover
/// may be unique to this codebase.
abstract contract Ownable {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                       CUSTOM ERRORS                        */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The caller is not authorized to call the function.
    error Unauthorized();

    /// @dev The `newOwner` cannot be the zero address.
    error NewOwnerIsZeroAddress();

    /// @dev The `pendingOwner` does not have a valid handover request.
    error NoHandoverRequest();

    /// @dev `bytes4(keccak256(bytes("Unauthorized()")))`.
    uint256 private constant _UNAUTHORIZED_ERROR_SELECTOR = 0x82b42900;

    /// @dev `bytes4(keccak256(bytes("NewOwnerIsZeroAddress()")))`.
    uint256 private constant _NEW_OWNER_IS_ZERO_ADDRESS_ERROR_SELECTOR = 0x7448fbae;

    /// @dev `bytes4(keccak256(bytes("NoHandoverRequest()")))`.
    uint256 private constant _NO_HANDOVER_REQUEST_ERROR_SELECTOR = 0x6f5e8818;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                           EVENTS                           */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The ownership is transferred from `oldOwner` to `newOwner`.
    /// This event is intentionally kept the same as OpenZeppelin's Ownable to be
    /// compatible with indexers and [EIP-173](https://eips.ethereum.org/EIPS/eip-173),
    /// despite it not being as lightweight as a single argument event.
    event OwnershipTransferred(address indexed oldOwner, address indexed newOwner);

    /// @dev An ownership handover to `pendingOwner` has been requested.
    event OwnershipHandoverRequested(address indexed pendingOwner);

    /// @dev The ownership handover to `pendingOwner` has been canceled.
    event OwnershipHandoverCanceled(address indexed pendingOwner);

    /// @dev `keccak256(bytes("OwnershipTransferred(address,address)"))`.
    uint256 private constant _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE =
        0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0;

    /// @dev `keccak256(bytes("OwnershipHandoverRequested(address)"))`.
    uint256 private constant _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE =
        0xdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d;

    /// @dev `keccak256(bytes("OwnershipHandoverCanceled(address)"))`.
    uint256 private constant _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE =
        0xfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                          STORAGE                           */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The owner slot is given by: `not(_OWNER_SLOT_NOT)`.
    /// It is intentionally choosen to be a high value
    /// to avoid collision with lower slots.
    /// The choice of manual storage layout is to enable compatibility
    /// with both regular and upgradeable contracts.
    uint256 private constant _OWNER_SLOT_NOT = 0x8b78c6d8;

    /// The ownership handover slot of `newOwner` is given by:
    /// ```
    ///     mstore(0x00, or(shl(96, user), _HANDOVER_SLOT_SEED))
    ///     let handoverSlot := keccak256(0x00, 0x20)
    /// ```
    /// It stores the expiry timestamp of the two-step ownership handover.
    uint256 private constant _HANDOVER_SLOT_SEED = 0x389a75e1;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                     INTERNAL FUNCTIONS                     */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Initializes the owner directly without authorization guard.
    /// This function must be called upon initialization,
    /// regardless of whether the contract is upgradeable or not.
    /// This is to enable generalization to both regular and upgradeable contracts,
    /// and to save gas in case the initial owner is not the caller.
    /// For performance reasons, this function will not check if there
    /// is an existing owner.
    function _initializeOwner(address newOwner) internal virtual {
        /// @solidity memory-safe-assembly
        assembly {
            // Clean the upper 96 bits.
            newOwner := shr(96, shl(96, newOwner))
            // Store the new value.
            sstore(not(_OWNER_SLOT_NOT), newOwner)
            // Emit the {OwnershipTransferred} event.
            log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)
        }
    }

    /// @dev Sets the owner directly without authorization guard.
    function _setOwner(address newOwner) internal virtual {
        /// @solidity memory-safe-assembly
        assembly {
            let ownerSlot := not(_OWNER_SLOT_NOT)
            // Clean the upper 96 bits.
            newOwner := shr(96, shl(96, newOwner))
            // Emit the {OwnershipTransferred} event.
            log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)
            // Store the new value.
            sstore(ownerSlot, newOwner)
        }
    }

    /// @dev Throws if the sender is not the owner.
    function _checkOwner() internal view virtual {
        /// @solidity memory-safe-assembly
        assembly {
            // If the caller is not the stored owner, revert.
            if iszero(eq(caller(), sload(not(_OWNER_SLOT_NOT)))) {
                mstore(0x00, _UNAUTHORIZED_ERROR_SELECTOR)
                revert(0x1c, 0x04)
            }
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                  PUBLIC UPDATE FUNCTIONS                   */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Allows the owner to transfer the ownership to `newOwner`.
    function transferOwnership(address newOwner) public payable virtual onlyOwner {
        /// @solidity memory-safe-assembly
        assembly {
            if iszero(shl(96, newOwner)) {
                mstore(0x00, _NEW_OWNER_IS_ZERO_ADDRESS_ERROR_SELECTOR)
                revert(0x1c, 0x04)
            }
        }
        _setOwner(newOwner);
    }

    /// @dev Allows the owner to renounce their ownership.
    function renounceOwnership() public payable virtual onlyOwner {
        _setOwner(address(0));
    }

    /// @dev Request a two-step ownership handover to the caller.
    /// The request will be automatically expire in 48 hours (172800 seconds) by default.
    function requestOwnershipHandover() public payable virtual {
        unchecked {
            uint256 expires = block.timestamp + ownershipHandoverValidFor();
            /// @solidity memory-safe-assembly
            assembly {
                // Compute and set the handover slot to `expires`.
                mstore(0x0c, _HANDOVER_SLOT_SEED)
                mstore(0x00, caller())
                sstore(keccak256(0x0c, 0x20), expires)
                // Emit the {OwnershipHandoverRequested} event.
                log2(0, 0, _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE, caller())
            }
        }
    }

    /// @dev Cancels the two-step ownership handover to the caller, if any.
    function cancelOwnershipHandover() public payable virtual {
        /// @solidity memory-safe-assembly
        assembly {
            // Compute and set the handover slot to 0.
            mstore(0x0c, _HANDOVER_SLOT_SEED)
            mstore(0x00, caller())
            sstore(keccak256(0x0c, 0x20), 0)
            // Emit the {OwnershipHandoverCanceled} event.
            log2(0, 0, _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE, caller())
        }
    }

    /// @dev Allows the owner to complete the two-step ownership handover to `pendingOwner`.
    /// Reverts if there is no existing ownership handover requested by `pendingOwner`.
    function completeOwnershipHandover(address pendingOwner) public payable virtual onlyOwner {
        /// @solidity memory-safe-assembly
        assembly {
            // Compute and set the handover slot to 0.
            mstore(0x0c, _HANDOVER_SLOT_SEED)
            mstore(0x00, pendingOwner)
            let handoverSlot := keccak256(0x0c, 0x20)
            // If the handover does not exist, or has expired.
            if gt(timestamp(), sload(handoverSlot)) {
                mstore(0x00, _NO_HANDOVER_REQUEST_ERROR_SELECTOR)
                revert(0x1c, 0x04)
            }
            // Set the handover slot to 0.
            sstore(handoverSlot, 0)
        }
        _setOwner(pendingOwner);
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                   PUBLIC READ FUNCTIONS                    */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns the owner of the contract.
    function owner() public view virtual returns (address result) {
        /// @solidity memory-safe-assembly
        assembly {
            result := sload(not(_OWNER_SLOT_NOT))
        }
    }

    /// @dev Returns the expiry timestamp for the two-step ownership handover to `pendingOwner`.
    function ownershipHandoverExpiresAt(address pendingOwner)
        public
        view
        virtual
        returns (uint256 result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            // Compute the handover slot.
            mstore(0x0c, _HANDOVER_SLOT_SEED)
            mstore(0x00, pendingOwner)
            // Load the handover slot.
            result := sload(keccak256(0x0c, 0x20))
        }
    }

    /// @dev Returns how long a two-step ownership handover is valid for in seconds.
    function ownershipHandoverValidFor() public view virtual returns (uint64) {
        return 48 * 3600;
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                         MODIFIERS                          */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Marks a function as only callable by the owner.
    modifier onlyOwner() virtual {
        _checkOwner();
        _;
    }
}

File 4 of 8 : ERC1155.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Minimalist and gas efficient standard ERC1155 implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC1155.sol)
abstract contract ERC1155 {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event TransferSingle(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256 id,
        uint256 amount
    );

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

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

    event URI(string value, uint256 indexed id);

    /*//////////////////////////////////////////////////////////////
                             ERC1155 STORAGE
    //////////////////////////////////////////////////////////////*/

    mapping(address => mapping(uint256 => uint256)) public balanceOf;

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

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

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

    /*//////////////////////////////////////////////////////////////
                              ERC1155 LOGIC
    //////////////////////////////////////////////////////////////*/

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

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

    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes calldata data
    ) public virtual {
        require(msg.sender == from || isApprovedForAll[from][msg.sender], "NOT_AUTHORIZED");

        balanceOf[from][id] -= amount;
        balanceOf[to][id] += amount;

        emit TransferSingle(msg.sender, from, to, id, amount);

        require(
            to.code.length == 0
                ? to != address(0)
                : ERC1155TokenReceiver(to).onERC1155Received(msg.sender, from, id, amount, data) ==
                    ERC1155TokenReceiver.onERC1155Received.selector,
            "UNSAFE_RECIPIENT"
        );
    }

    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata amounts,
        bytes calldata data
    ) public virtual {
        require(ids.length == amounts.length, "LENGTH_MISMATCH");

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

        // Storing these outside the loop saves ~15 gas per iteration.
        uint256 id;
        uint256 amount;

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

            balanceOf[from][id] -= amount;
            balanceOf[to][id] += amount;

            // An array can't have a total length
            // larger than the max uint256 value.
            unchecked {
                ++i;
            }
        }

        emit TransferBatch(msg.sender, from, to, ids, amounts);

        require(
            to.code.length == 0
                ? to != address(0)
                : ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, from, ids, amounts, data) ==
                    ERC1155TokenReceiver.onERC1155BatchReceived.selector,
            "UNSAFE_RECIPIENT"
        );
    }

    function balanceOfBatch(address[] calldata owners, uint256[] calldata ids)
        public
        view
        virtual
        returns (uint256[] memory balances)
    {
        require(owners.length == ids.length, "LENGTH_MISMATCH");

        balances = new uint256[](owners.length);

        // Unchecked because the only math done is incrementing
        // the array index counter which cannot possibly overflow.
        unchecked {
            for (uint256 i = 0; i < owners.length; ++i) {
                balances[i] = balanceOf[owners[i]][ids[i]];
            }
        }
    }

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

    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
        return
            interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165
            interfaceId == 0xd9b67a26 || // ERC165 Interface ID for ERC1155
            interfaceId == 0x0e89341c; // ERC165 Interface ID for ERC1155MetadataURI
    }

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

    function _mint(
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) internal virtual {
        balanceOf[to][id] += amount;

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

        require(
            to.code.length == 0
                ? to != address(0)
                : ERC1155TokenReceiver(to).onERC1155Received(msg.sender, address(0), id, amount, data) ==
                    ERC1155TokenReceiver.onERC1155Received.selector,
            "UNSAFE_RECIPIENT"
        );
    }

    function _batchMint(
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {
        uint256 idsLength = ids.length; // Saves MLOADs.

        require(idsLength == amounts.length, "LENGTH_MISMATCH");

        for (uint256 i = 0; i < idsLength; ) {
            balanceOf[to][ids[i]] += amounts[i];

            // An array can't have a total length
            // larger than the max uint256 value.
            unchecked {
                ++i;
            }
        }

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

        require(
            to.code.length == 0
                ? to != address(0)
                : ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, address(0), ids, amounts, data) ==
                    ERC1155TokenReceiver.onERC1155BatchReceived.selector,
            "UNSAFE_RECIPIENT"
        );
    }

    function _batchBurn(
        address from,
        uint256[] memory ids,
        uint256[] memory amounts
    ) internal virtual {
        uint256 idsLength = ids.length; // Saves MLOADs.

        require(idsLength == amounts.length, "LENGTH_MISMATCH");

        for (uint256 i = 0; i < idsLength; ) {
            balanceOf[from][ids[i]] -= amounts[i];

            // An array can't have a total length
            // larger than the max uint256 value.
            unchecked {
                ++i;
            }
        }

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

    function _burn(
        address from,
        uint256 id,
        uint256 amount
    ) internal virtual {
        balanceOf[from][id] -= amount;

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

/// @notice A generic interface for a contract which properly accepts ERC1155 tokens.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC1155.sol)
abstract contract ERC1155TokenReceiver {
    function onERC1155Received(
        address,
        address,
        uint256,
        uint256,
        bytes calldata
    ) external virtual returns (bytes4) {
        return ERC1155TokenReceiver.onERC1155Received.selector;
    }

    function onERC1155BatchReceived(
        address,
        address,
        uint256[] calldata,
        uint256[] calldata,
        bytes calldata
    ) external virtual returns (bytes4) {
        return ERC1155TokenReceiver.onERC1155BatchReceived.selector;
    }
}

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

pragma solidity ^0.8.0;

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

File 6 of 8 : IERC1155.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

File 7 of 8 : IMetadataRenderer.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;

interface IMetadataRenderer {
    function tokenURI(uint256 id) external view returns (string memory);
}

File 8 of 8 : IERC4906.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

interface IERC4906 {
    /// @dev This event emits when the metadata of a token is changed.
    /// So that the third-party platforms such as NFT market could
    /// timely update the images and related attributes of the NFT.
    event MetadataUpdate(uint256 _tokenId);

    /// @dev This event emits when the metadata of a range of tokens is changed.
    /// So that the third-party platforms such as NFT market could
    /// timely update the images and related attributes of the NFTs.
    event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);
}

Settings
{
  "remappings": [
    "ERC721A/=lib/ERC721A/contracts/",
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "forge-std/=lib/forge-std/src/",
    "openzeppelin/=lib/openzeppelin-contracts/contracts/",
    "solmate/=lib/solmate/src/",
    "solady/=lib/solady/src/",
    "fundrop/=src/Fundrop/",
    "operator-filter-registry/=lib/operator-filter-registry/src/",
    "erc4626-tests/=lib/operator-filter-registry/lib/openzeppelin-contracts/lib/erc4626-tests/",
    "openzeppelin-contracts-upgradeable/=lib/operator-filter-registry/lib/openzeppelin-contracts-upgradeable/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 250000
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "paris",
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[],"name":"MintClosed","type":"error"},{"inputs":[],"name":"MintedAlready","type":"error"},{"inputs":[],"name":"NewOwnerIsZeroAddress","type":"error"},{"inputs":[],"name":"NoHandoverRequest","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldOwner","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":"amounts","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":"amount","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"tokens","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"adminMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"owners","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"balances","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cancelOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"completeOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"metadataRenderer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokens","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"uint16","name":"round","type":"uint16"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintEnd","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"result","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"ownershipHandoverExpiresAt","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ownershipHandoverValidFor","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"requestOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_metadataRenderer","type":"address"}],"name":"setMetadataRenderer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintEnd","type":"uint256"}],"name":"setMintEnd","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_signer","type":"address"}],"name":"setSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"signer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]

608060405234801561001057600080fd5b5061001a3261001f565b61005b565b6001600160a01b0316638b78c6d8198190558060007f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08180a350565b6121ff8061006a6000396000f3fe6080604052600436106101955760003560e01c8063715018a6116100e1578063ea2b4ab21161008a578063f242432a11610064578063f242432a146104b0578063f2fde38b146104d0578063fd4fe8a8146104e3578063fee81cf41461050357600080fd5b8063ea2b4ab214610467578063eb20614e1461047d578063f04e283e1461049d57600080fd5b8063a22cb465116100bb578063a22cb465146103ee578063d7533f021461040e578063e985e9c51461042c57600080fd5b8063715018a614610392578063812015b91461039a5780638da5cb5b146103ba57600080fd5b80632eb2c2d61161014357806354d1f13d1161011d57806354d1f13d1461033d5780636c19e78314610345578063703199701461036557600080fd5b80632eb2c2d6146102dd5780634e1273f4146102fd578063525b6ba01461032a57600080fd5b80630e89341c116101745780630e89341c14610261578063238ac9331461028157806325692962146102d357600080fd5b8062fdd58e1461019a57806301ffc9a7146101e257806306fdde0314610212575b600080fd5b3480156101a657600080fd5b506101cf6101b5366004611829565b600060208181529281526040808220909352908152205481565b6040519081526020015b60405180910390f35b3480156101ee57600080fd5b506102026101fd366004611881565b610536565b60405190151581526020016101d9565b34801561021e57600080fd5b5060408051808201909152601181527f2166756e64726f7020537469636b65727300000000000000000000000000000060208201525b6040516101d9919061190c565b34801561026d57600080fd5b5061025461027c36600461191f565b6105fa565b34801561028d57600080fd5b506002546102ae9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d9565b6102db6106b0565b005b3480156102e957600080fd5b506102db6102f83660046119c6565b610700565b34801561030957600080fd5b5061031d610318366004611a81565b610af6565b6040516101d99190611b28565b6102db610338366004611b3b565b610c6d565b6102db610e70565b34801561035157600080fd5b506102db610360366004611bf1565b610eac565b34801561037157600080fd5b506003546102ae9073ffffffffffffffffffffffffffffffffffffffff1681565b6102db610efb565b3480156103a657600080fd5b506102db6103b5366004611c0c565b610f0f565b3480156103c657600080fd5b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927546102ae565b3480156103fa57600080fd5b506102db610409366004611c8d565b610f9a565b34801561041a57600080fd5b506040516202a30081526020016101d9565b34801561043857600080fd5b50610202610447366004611cc9565b600160209081526000928352604080842090915290825290205460ff1681565b34801561047357600080fd5b506101cf60045481565b34801561048957600080fd5b506102db61049836600461191f565b611031565b6102db6104ab366004611bf1565b61103e565b3480156104bc57600080fd5b506102db6104cb366004611cfc565b61107e565b6102db6104de366004611bf1565b611384565b3480156104ef57600080fd5b506102db6104fe366004611bf1565b6113ab565b34801561050f57600080fd5b506101cf61051e366004611bf1565b63389a75e1600c908152600091909152602090205490565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a70000000000000000000000000000000000000000000000000000000014806105c957507fffffffff0000000000000000000000000000000000000000000000000000000082167fd9b67a2600000000000000000000000000000000000000000000000000000000145b806105f457507fffffffff000000000000000000000000000000000000000000000000000000008216155b92915050565b6003546040517fc87b56dd0000000000000000000000000000000000000000000000000000000081526004810183905260609173ffffffffffffffffffffffffffffffffffffffff169063c87b56dd90602401600060405180830381865afa15801561066a573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105f49190810190611da3565b60006202a30067ffffffffffffffff164201905063389a75e1600c5233600052806020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d600080a250565b84831461076e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f4c454e4754485f4d49534d41544348000000000000000000000000000000000060448201526064015b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff891614806107c2575073ffffffffffffffffffffffffffffffffffffffff8816600090815260016020908152604080832033845290915290205460ff165b610828576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a45440000000000000000000000000000000000006044820152606401610765565b60008060005b878110156108fd5788888281811061084857610848611e6e565b90506020020135925086868281811061086357610863611e6e565b73ffffffffffffffffffffffffffffffffffffffff8e16600090815260208181526040808320898452825282208054939091029490940135955085939250906108ad908490611ecc565b909155505073ffffffffffffffffffffffffffffffffffffffff8a16600090815260208181526040808320868452909152812080548492906108f0908490611edf565b909155505060010161082e565b508873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8b8b8b8b6040516109789493929190611f3d565b60405180910390a473ffffffffffffffffffffffffffffffffffffffff89163b15610a6a576040517fbc197c81000000000000000000000000000000000000000000000000000000008082529073ffffffffffffffffffffffffffffffffffffffff8b169063bc197c81906109ff9033908f908e908e908e908e908e908e90600401611fad565b6020604051808303816000875af1158015610a1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a42919061201e565b7fffffffff000000000000000000000000000000000000000000000000000000001614610a84565b73ffffffffffffffffffffffffffffffffffffffff891615155b610aea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f554e534146455f524543495049454e54000000000000000000000000000000006044820152606401610765565b50505050505050505050565b6060838214610b61576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f4c454e4754485f4d49534d4154434800000000000000000000000000000000006044820152606401610765565b8367ffffffffffffffff811115610b7a57610b7a611d74565b604051908082528060200260200182016040528015610ba3578160200160208202803683370190505b50905060005b84811015610c6457600080878784818110610bc657610bc6611e6e565b9050602002016020810190610bdb9190611bf1565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000858584818110610c2957610c29611e6e565b90506020020135815260200190815260200160002054828281518110610c5157610c51611e6e565b6020908102919091010152600101610ba9565b50949350505050565b60045461ffff84163360601b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000161790421115610cd6576040517f589ed34b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526005602052604090205460ff1615610d1f576040517f96dd8aac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610d5c33868b8b8b8b604051602001610d3f9695949392919061207d565b6040516020818303038152906040528051906020012085856113fa565b60025490915073ffffffffffffffffffffffffffffffffffffffff808316911614610db3576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526005602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905581518a820281810183019093528a8152610e659233928d918d9182919085019084908082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c91829185019084908082843760009201829052506040805160208101909152908152925061146a915050565b505050505050505050565b63389a75e1600c523360005260006020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92600080a2565b610eb4611764565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610f03611764565b610f0d600061179a565b565b610f17611764565b610f93858585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080890282810182019093528882529093508892508791829185019084908082843760009201829052506040805160208101909152908152925061146a915050565b5050505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b611039611764565b600455565b611046611764565b63389a75e1600c52806000526020600c20805442111561106e57636f5e88186000526004601cfd5b6000905561107b8161179a565b50565b3373ffffffffffffffffffffffffffffffffffffffff871614806110d2575073ffffffffffffffffffffffffffffffffffffffff8616600090815260016020908152604080832033845290915290205460ff165b611138576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a45440000000000000000000000000000000000006044820152606401610765565b73ffffffffffffffffffffffffffffffffffffffff861660009081526020818152604080832087845290915281208054859290611176908490611ecc565b909155505073ffffffffffffffffffffffffffffffffffffffff8516600090815260208181526040808320878452909152812080548592906111b9908490611edf565b9091555050604080518581526020810185905273ffffffffffffffffffffffffffffffffffffffff808816929089169133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a473ffffffffffffffffffffffffffffffffffffffff85163b156112fc576040517ff23a6e61000000000000000000000000000000000000000000000000000000008082529073ffffffffffffffffffffffffffffffffffffffff87169063f23a6e61906112919033908b908a908a908a908a906004016120f6565b6020604051808303816000875af11580156112b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112d4919061201e565b7fffffffff000000000000000000000000000000000000000000000000000000001614611316565b73ffffffffffffffffffffffffffffffffffffffff851615155b61137c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f554e534146455f524543495049454e54000000000000000000000000000000006044820152606401610765565b505050505050565b61138c611764565b8060601b6113a257637448fbae6000526004601cfd5b61107b8161179a565b6113b3611764565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600060418218611463576040516040846040377f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a06060511161145f5784600052604084013560001a602052602060406080600060015afa5060006060523d6060185191505b6040525b9392505050565b8251825181146114d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f4c454e4754485f4d49534d4154434800000000000000000000000000000000006044820152606401610765565b60005b8181101561157f578381815181106114f3576114f3611e6e565b60200260200101516000808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600087848151811061154d5761154d611e6e565b6020026020010151815260200190815260200160002060008282546115729190611edf565b90915550506001016114d9565b508473ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb87876040516115f792919061213c565b60405180910390a473ffffffffffffffffffffffffffffffffffffffff85163b156116e4576040517fbc197c81000000000000000000000000000000000000000000000000000000008082529073ffffffffffffffffffffffffffffffffffffffff87169063bc197c81906116799033906000908a908a908a9060040161216a565b6020604051808303816000875af1158015611698573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116bc919061201e565b7fffffffff0000000000000000000000000000000000000000000000000000000016146116fe565b73ffffffffffffffffffffffffffffffffffffffff851615155b610f93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f554e534146455f524543495049454e54000000000000000000000000000000006044820152606401610765565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927543314610f0d576382b429006000526004601cfd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927805473ffffffffffffffffffffffffffffffffffffffff9092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a355565b803573ffffffffffffffffffffffffffffffffffffffff8116811461182457600080fd5b919050565b6000806040838503121561183c57600080fd5b61184583611800565b946020939093013593505050565b7fffffffff000000000000000000000000000000000000000000000000000000008116811461107b57600080fd5b60006020828403121561189357600080fd5b813561146381611853565b60005b838110156118b95781810151838201526020016118a1565b50506000910152565b600081518084526118da81602086016020860161189e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061146360208301846118c2565b60006020828403121561193157600080fd5b5035919050565b60008083601f84011261194a57600080fd5b50813567ffffffffffffffff81111561196257600080fd5b6020830191508360208260051b850101111561197d57600080fd5b9250929050565b60008083601f84011261199657600080fd5b50813567ffffffffffffffff8111156119ae57600080fd5b60208301915083602082850101111561197d57600080fd5b60008060008060008060008060a0898b0312156119e257600080fd5b6119eb89611800565b97506119f960208a01611800565b9650604089013567ffffffffffffffff80821115611a1657600080fd5b611a228c838d01611938565b909850965060608b0135915080821115611a3b57600080fd5b611a478c838d01611938565b909650945060808b0135915080821115611a6057600080fd5b50611a6d8b828c01611984565b999c989b5096995094979396929594505050565b60008060008060408587031215611a9757600080fd5b843567ffffffffffffffff80821115611aaf57600080fd5b611abb88838901611938565b90965094506020870135915080821115611ad457600080fd5b50611ae187828801611938565b95989497509550505050565b600081518084526020808501945080840160005b83811015611b1d57815187529582019590820190600101611b01565b509495945050505050565b6020815260006114636020830184611aed565b60008060008060008060006080888a031215611b5657600080fd5b873567ffffffffffffffff80821115611b6e57600080fd5b611b7a8b838c01611938565b909950975060208a0135915080821115611b9357600080fd5b611b9f8b838c01611938565b909750955060408a0135915061ffff82168214611bbb57600080fd5b90935060608901359080821115611bd157600080fd5b50611bde8a828b01611984565b989b979a50959850939692959293505050565b600060208284031215611c0357600080fd5b61146382611800565b600080600080600060608688031215611c2457600080fd5b611c2d86611800565b9450602086013567ffffffffffffffff80821115611c4a57600080fd5b611c5689838a01611938565b90965094506040880135915080821115611c6f57600080fd5b50611c7c88828901611938565b969995985093965092949392505050565b60008060408385031215611ca057600080fd5b611ca983611800565b915060208301358015158114611cbe57600080fd5b809150509250929050565b60008060408385031215611cdc57600080fd5b611ce583611800565b9150611cf360208401611800565b90509250929050565b60008060008060008060a08789031215611d1557600080fd5b611d1e87611800565b9550611d2c60208801611800565b94506040870135935060608701359250608087013567ffffffffffffffff811115611d5657600080fd5b611d6289828a01611984565b979a9699509497509295939492505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215611db557600080fd5b815167ffffffffffffffff80821115611dcd57600080fd5b818401915084601f830112611de157600080fd5b815181811115611df357611df3611d74565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611e3957611e39611d74565b81604052828152876020848701011115611e5257600080fd5b611e6383602083016020880161189e565b979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105f4576105f4611e9d565b808201808211156105f4576105f4611e9d565b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115611f2457600080fd5b8260051b80836020870137939093016020019392505050565b604081526000611f51604083018688611ef2565b8281036020840152611e63818587611ef2565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b600073ffffffffffffffffffffffffffffffffffffffff808b168352808a1660208401525060a06040830152611fe760a08301888a611ef2565b8281036060840152611ffa818789611ef2565b9050828103608084015261200f818587611f64565b9b9a5050505050505050505050565b60006020828403121561203057600080fd5b815161146381611853565b60007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83111561206a57600080fd5b8260051b80838637939093019392505050565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008760601b1681527fffff0000000000000000000000000000000000000000000000000000000000008660f01b16601482015260006120ea6120e360168401878961203b565b848661203b565b98975050505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808916835280881660208401525085604083015284606083015260a060808301526120ea60a083018486611f64565b60408152600061214f6040830185611aed565b82810360208401526121618185611aed565b95945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525060a060408301526121a360a0830186611aed565b82810360608401526121b58186611aed565b905082810360808401526120ea81856118c256fea26469706673582212204f435c2221be3df7ed00f719688c96d8efeb99481b1d32738bd68358ff82ec9764736f6c63430008140033

Deployed Bytecode

0x6080604052600436106101955760003560e01c8063715018a6116100e1578063ea2b4ab21161008a578063f242432a11610064578063f242432a146104b0578063f2fde38b146104d0578063fd4fe8a8146104e3578063fee81cf41461050357600080fd5b8063ea2b4ab214610467578063eb20614e1461047d578063f04e283e1461049d57600080fd5b8063a22cb465116100bb578063a22cb465146103ee578063d7533f021461040e578063e985e9c51461042c57600080fd5b8063715018a614610392578063812015b91461039a5780638da5cb5b146103ba57600080fd5b80632eb2c2d61161014357806354d1f13d1161011d57806354d1f13d1461033d5780636c19e78314610345578063703199701461036557600080fd5b80632eb2c2d6146102dd5780634e1273f4146102fd578063525b6ba01461032a57600080fd5b80630e89341c116101745780630e89341c14610261578063238ac9331461028157806325692962146102d357600080fd5b8062fdd58e1461019a57806301ffc9a7146101e257806306fdde0314610212575b600080fd5b3480156101a657600080fd5b506101cf6101b5366004611829565b600060208181529281526040808220909352908152205481565b6040519081526020015b60405180910390f35b3480156101ee57600080fd5b506102026101fd366004611881565b610536565b60405190151581526020016101d9565b34801561021e57600080fd5b5060408051808201909152601181527f2166756e64726f7020537469636b65727300000000000000000000000000000060208201525b6040516101d9919061190c565b34801561026d57600080fd5b5061025461027c36600461191f565b6105fa565b34801561028d57600080fd5b506002546102ae9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d9565b6102db6106b0565b005b3480156102e957600080fd5b506102db6102f83660046119c6565b610700565b34801561030957600080fd5b5061031d610318366004611a81565b610af6565b6040516101d99190611b28565b6102db610338366004611b3b565b610c6d565b6102db610e70565b34801561035157600080fd5b506102db610360366004611bf1565b610eac565b34801561037157600080fd5b506003546102ae9073ffffffffffffffffffffffffffffffffffffffff1681565b6102db610efb565b3480156103a657600080fd5b506102db6103b5366004611c0c565b610f0f565b3480156103c657600080fd5b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927546102ae565b3480156103fa57600080fd5b506102db610409366004611c8d565b610f9a565b34801561041a57600080fd5b506040516202a30081526020016101d9565b34801561043857600080fd5b50610202610447366004611cc9565b600160209081526000928352604080842090915290825290205460ff1681565b34801561047357600080fd5b506101cf60045481565b34801561048957600080fd5b506102db61049836600461191f565b611031565b6102db6104ab366004611bf1565b61103e565b3480156104bc57600080fd5b506102db6104cb366004611cfc565b61107e565b6102db6104de366004611bf1565b611384565b3480156104ef57600080fd5b506102db6104fe366004611bf1565b6113ab565b34801561050f57600080fd5b506101cf61051e366004611bf1565b63389a75e1600c908152600091909152602090205490565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a70000000000000000000000000000000000000000000000000000000014806105c957507fffffffff0000000000000000000000000000000000000000000000000000000082167fd9b67a2600000000000000000000000000000000000000000000000000000000145b806105f457507fffffffff000000000000000000000000000000000000000000000000000000008216155b92915050565b6003546040517fc87b56dd0000000000000000000000000000000000000000000000000000000081526004810183905260609173ffffffffffffffffffffffffffffffffffffffff169063c87b56dd90602401600060405180830381865afa15801561066a573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105f49190810190611da3565b60006202a30067ffffffffffffffff164201905063389a75e1600c5233600052806020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d600080a250565b84831461076e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f4c454e4754485f4d49534d41544348000000000000000000000000000000000060448201526064015b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff891614806107c2575073ffffffffffffffffffffffffffffffffffffffff8816600090815260016020908152604080832033845290915290205460ff165b610828576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a45440000000000000000000000000000000000006044820152606401610765565b60008060005b878110156108fd5788888281811061084857610848611e6e565b90506020020135925086868281811061086357610863611e6e565b73ffffffffffffffffffffffffffffffffffffffff8e16600090815260208181526040808320898452825282208054939091029490940135955085939250906108ad908490611ecc565b909155505073ffffffffffffffffffffffffffffffffffffffff8a16600090815260208181526040808320868452909152812080548492906108f0908490611edf565b909155505060010161082e565b508873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8b8b8b8b6040516109789493929190611f3d565b60405180910390a473ffffffffffffffffffffffffffffffffffffffff89163b15610a6a576040517fbc197c81000000000000000000000000000000000000000000000000000000008082529073ffffffffffffffffffffffffffffffffffffffff8b169063bc197c81906109ff9033908f908e908e908e908e908e908e90600401611fad565b6020604051808303816000875af1158015610a1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a42919061201e565b7fffffffff000000000000000000000000000000000000000000000000000000001614610a84565b73ffffffffffffffffffffffffffffffffffffffff891615155b610aea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f554e534146455f524543495049454e54000000000000000000000000000000006044820152606401610765565b50505050505050505050565b6060838214610b61576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f4c454e4754485f4d49534d4154434800000000000000000000000000000000006044820152606401610765565b8367ffffffffffffffff811115610b7a57610b7a611d74565b604051908082528060200260200182016040528015610ba3578160200160208202803683370190505b50905060005b84811015610c6457600080878784818110610bc657610bc6611e6e565b9050602002016020810190610bdb9190611bf1565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000858584818110610c2957610c29611e6e565b90506020020135815260200190815260200160002054828281518110610c5157610c51611e6e565b6020908102919091010152600101610ba9565b50949350505050565b60045461ffff84163360601b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000161790421115610cd6576040517f589ed34b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526005602052604090205460ff1615610d1f576040517f96dd8aac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610d5c33868b8b8b8b604051602001610d3f9695949392919061207d565b6040516020818303038152906040528051906020012085856113fa565b60025490915073ffffffffffffffffffffffffffffffffffffffff808316911614610db3576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526005602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905581518a820281810183019093528a8152610e659233928d918d9182919085019084908082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c91829185019084908082843760009201829052506040805160208101909152908152925061146a915050565b505050505050505050565b63389a75e1600c523360005260006020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92600080a2565b610eb4611764565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610f03611764565b610f0d600061179a565b565b610f17611764565b610f93858585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080890282810182019093528882529093508892508791829185019084908082843760009201829052506040805160208101909152908152925061146a915050565b5050505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b611039611764565b600455565b611046611764565b63389a75e1600c52806000526020600c20805442111561106e57636f5e88186000526004601cfd5b6000905561107b8161179a565b50565b3373ffffffffffffffffffffffffffffffffffffffff871614806110d2575073ffffffffffffffffffffffffffffffffffffffff8616600090815260016020908152604080832033845290915290205460ff165b611138576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a45440000000000000000000000000000000000006044820152606401610765565b73ffffffffffffffffffffffffffffffffffffffff861660009081526020818152604080832087845290915281208054859290611176908490611ecc565b909155505073ffffffffffffffffffffffffffffffffffffffff8516600090815260208181526040808320878452909152812080548592906111b9908490611edf565b9091555050604080518581526020810185905273ffffffffffffffffffffffffffffffffffffffff808816929089169133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a473ffffffffffffffffffffffffffffffffffffffff85163b156112fc576040517ff23a6e61000000000000000000000000000000000000000000000000000000008082529073ffffffffffffffffffffffffffffffffffffffff87169063f23a6e61906112919033908b908a908a908a908a906004016120f6565b6020604051808303816000875af11580156112b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112d4919061201e565b7fffffffff000000000000000000000000000000000000000000000000000000001614611316565b73ffffffffffffffffffffffffffffffffffffffff851615155b61137c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f554e534146455f524543495049454e54000000000000000000000000000000006044820152606401610765565b505050505050565b61138c611764565b8060601b6113a257637448fbae6000526004601cfd5b61107b8161179a565b6113b3611764565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600060418218611463576040516040846040377f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a06060511161145f5784600052604084013560001a602052602060406080600060015afa5060006060523d6060185191505b6040525b9392505050565b8251825181146114d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f4c454e4754485f4d49534d4154434800000000000000000000000000000000006044820152606401610765565b60005b8181101561157f578381815181106114f3576114f3611e6e565b60200260200101516000808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600087848151811061154d5761154d611e6e565b6020026020010151815260200190815260200160002060008282546115729190611edf565b90915550506001016114d9565b508473ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb87876040516115f792919061213c565b60405180910390a473ffffffffffffffffffffffffffffffffffffffff85163b156116e4576040517fbc197c81000000000000000000000000000000000000000000000000000000008082529073ffffffffffffffffffffffffffffffffffffffff87169063bc197c81906116799033906000908a908a908a9060040161216a565b6020604051808303816000875af1158015611698573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116bc919061201e565b7fffffffff0000000000000000000000000000000000000000000000000000000016146116fe565b73ffffffffffffffffffffffffffffffffffffffff851615155b610f93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f554e534146455f524543495049454e54000000000000000000000000000000006044820152606401610765565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927543314610f0d576382b429006000526004601cfd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927805473ffffffffffffffffffffffffffffffffffffffff9092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a355565b803573ffffffffffffffffffffffffffffffffffffffff8116811461182457600080fd5b919050565b6000806040838503121561183c57600080fd5b61184583611800565b946020939093013593505050565b7fffffffff000000000000000000000000000000000000000000000000000000008116811461107b57600080fd5b60006020828403121561189357600080fd5b813561146381611853565b60005b838110156118b95781810151838201526020016118a1565b50506000910152565b600081518084526118da81602086016020860161189e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061146360208301846118c2565b60006020828403121561193157600080fd5b5035919050565b60008083601f84011261194a57600080fd5b50813567ffffffffffffffff81111561196257600080fd5b6020830191508360208260051b850101111561197d57600080fd5b9250929050565b60008083601f84011261199657600080fd5b50813567ffffffffffffffff8111156119ae57600080fd5b60208301915083602082850101111561197d57600080fd5b60008060008060008060008060a0898b0312156119e257600080fd5b6119eb89611800565b97506119f960208a01611800565b9650604089013567ffffffffffffffff80821115611a1657600080fd5b611a228c838d01611938565b909850965060608b0135915080821115611a3b57600080fd5b611a478c838d01611938565b909650945060808b0135915080821115611a6057600080fd5b50611a6d8b828c01611984565b999c989b5096995094979396929594505050565b60008060008060408587031215611a9757600080fd5b843567ffffffffffffffff80821115611aaf57600080fd5b611abb88838901611938565b90965094506020870135915080821115611ad457600080fd5b50611ae187828801611938565b95989497509550505050565b600081518084526020808501945080840160005b83811015611b1d57815187529582019590820190600101611b01565b509495945050505050565b6020815260006114636020830184611aed565b60008060008060008060006080888a031215611b5657600080fd5b873567ffffffffffffffff80821115611b6e57600080fd5b611b7a8b838c01611938565b909950975060208a0135915080821115611b9357600080fd5b611b9f8b838c01611938565b909750955060408a0135915061ffff82168214611bbb57600080fd5b90935060608901359080821115611bd157600080fd5b50611bde8a828b01611984565b989b979a50959850939692959293505050565b600060208284031215611c0357600080fd5b61146382611800565b600080600080600060608688031215611c2457600080fd5b611c2d86611800565b9450602086013567ffffffffffffffff80821115611c4a57600080fd5b611c5689838a01611938565b90965094506040880135915080821115611c6f57600080fd5b50611c7c88828901611938565b969995985093965092949392505050565b60008060408385031215611ca057600080fd5b611ca983611800565b915060208301358015158114611cbe57600080fd5b809150509250929050565b60008060408385031215611cdc57600080fd5b611ce583611800565b9150611cf360208401611800565b90509250929050565b60008060008060008060a08789031215611d1557600080fd5b611d1e87611800565b9550611d2c60208801611800565b94506040870135935060608701359250608087013567ffffffffffffffff811115611d5657600080fd5b611d6289828a01611984565b979a9699509497509295939492505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215611db557600080fd5b815167ffffffffffffffff80821115611dcd57600080fd5b818401915084601f830112611de157600080fd5b815181811115611df357611df3611d74565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611e3957611e39611d74565b81604052828152876020848701011115611e5257600080fd5b611e6383602083016020880161189e565b979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105f4576105f4611e9d565b808201808211156105f4576105f4611e9d565b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115611f2457600080fd5b8260051b80836020870137939093016020019392505050565b604081526000611f51604083018688611ef2565b8281036020840152611e63818587611ef2565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b600073ffffffffffffffffffffffffffffffffffffffff808b168352808a1660208401525060a06040830152611fe760a08301888a611ef2565b8281036060840152611ffa818789611ef2565b9050828103608084015261200f818587611f64565b9b9a5050505050505050505050565b60006020828403121561203057600080fd5b815161146381611853565b60007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83111561206a57600080fd5b8260051b80838637939093019392505050565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008760601b1681527fffff0000000000000000000000000000000000000000000000000000000000008660f01b16601482015260006120ea6120e360168401878961203b565b848661203b565b98975050505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808916835280881660208401525085604083015284606083015260a060808301526120ea60a083018486611f64565b60408152600061214f6040830185611aed565b82810360208401526121618185611aed565b95945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525060a060408301526121a360a0830186611aed565b82810360608401526121b58186611aed565b905082810360808401526120ea81856118c256fea26469706673582212204f435c2221be3df7ed00f719688c96d8efeb99481b1d32738bd68358ff82ec9764736f6c63430008140033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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

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