Forkchoice Ethereum Mainnet

Address Contract Verified

Address 0x38ADA9fff969f60cAB9FC1f0db3E17585e23ea89
Balance 0 ETH
Nonce 1
Code Size 5546 bytes
Indexed Transactions 0 (1 on-chain, 1.4% indexed)
External Etherscan · Sourcify

Contract Bytecode

5546 bytes
0x608060405234801561001057600080fd5b50600436106101415760003560e01c80636a627842116100b8578063b88d4fde1161007c578063b88d4fde146102bf578063c87b56dd146102d2578063e0df5b6f146102e5578063e985e9c5146102f8578063eac989f814610326578063fac9ac2e1461032e57600080fd5b80636a6278421461026b57806370a082311461027e5780638da5cb5b1461029157806395d89b41146102a4578063a22cb465146102ac57600080fd5b806313af40351161010a57806313af4035146101f057806313faede61461020357806323b872dd1461022a5780633ccfd60b1461023d57806342842e0e146102455780636352211e1461025857600080fd5b80629a9b7b1461014657806301ffc9a71461016257806306fdde0314610185578063081812fc1461019a578063095ea7b3146101db575b600080fd5b61014f60085481565b6040519081526020015b60405180910390f35b610175610170366004611071565b610355565b6040519015158152602001610159565b61018d6103a7565b6040516101599190611095565b6101c36101a83660046110ea565b6004602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610159565b6101ee6101e936600461111a565b610435565b005b6101ee6101fe366004611144565b61051c565b61014f7f0000000000000000000000000000000000000000003b8e97d229a2d54800000081565b6101ee61023836600461115f565b610592565b6101ee610759565b6101ee61025336600461115f565b6108da565b6101c36102663660046110ea565b6109af565b61014f610279366004611144565b610a06565b61014f61028c366004611144565b610b34565b6006546101c3906001600160a01b031681565b61018d610b97565b6101ee6102ba3660046111a9565b610ba4565b6101ee6102cd3660046111e0565b610c10565b61018d6102e03660046110ea565b610cd5565b6101ee6102f3366004611291565b610d69565b610175610306366004611342565b600560209081526000928352604080842090915290825290205460ff1681565b61018d610dd7565b6101c37f000000000000000000000000dc98c5543f3004debfaad8966ec403093d0aa4a881565b60006301ffc9a760e01b6001600160e01b03198316148061038657506380ac58cd60e01b6001600160e01b03198316145b806103a15750635b5e139f60e01b6001600160e01b03198316145b92915050565b600080546103b490611375565b80601f01602080910402602001604051908101604052809291908181526020018280546103e090611375565b801561042d5780601f106104025761010080835404028352916020019161042d565b820191906000526020600020905b81548152906001019060200180831161041057829003601f168201915b505050505081565b6000818152600260205260409020546001600160a01b03163381148061047e57506001600160a01b038116600090815260056020908152604080832033845290915290205460ff165b6104c05760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064015b60405180910390fd5b60008281526004602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6006546001600160a01b031633146105465760405162461bcd60e51b81526004016104b7906113af565b600680546001600160a01b0319166001600160a01b03831690811790915560405133907f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d7690600090a350565b6000818152600260205260409020546001600160a01b038481169116146105e85760405162461bcd60e51b815260206004820152600a60248201526957524f4e475f46524f4d60b01b60448201526064016104b7565b6001600160a01b0382166106325760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b60448201526064016104b7565b336001600160a01b038416148061066c57506001600160a01b038316600090815260056020908152604080832033845290915290205460ff165b8061068d57506000818152600460205260409020546001600160a01b031633145b6106ca5760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064016104b7565b6001600160a01b0380841660008181526003602090815260408083208054600019019055938616808352848320805460010190558583526002825284832080546001600160a01b03199081168317909155600490925284832080549092169091559251849392917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6006546001600160a01b031633146107835760405162461bcd60e51b81526004016104b7906113af565b6040516370a0823160e01b81523060048201526000907f000000000000000000000000dc98c5543f3004debfaad8966ec403093d0aa4a86001600160a01b0316906370a0823190602401602060405180830381865afa1580156107ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080e91906113d5565b60405163a9059cbb60e01b8152336004820152602481018290529091507f000000000000000000000000dc98c5543f3004debfaad8966ec403093d0aa4a86001600160a01b03169063a9059cbb906044016020604051808303816000875af115801561087e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108a291906113ee565b506040518181527f5b6b431d4476a211bb7d41c20d1aab9ae2321deee0d20be3d9fc9b1093fa6e3d906020015b60405180910390a150565b6108e5838383610592565b6001600160a01b0382163b158061098e5750604051630a85bd0160e11b8082523360048301526001600160a01b03858116602484015260448301849052608060648401526000608484015290919084169063150b7a029060a4016020604051808303816000875af115801561095e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610982919061140b565b6001600160e01b031916145b6109aa5760405162461bcd60e51b81526004016104b790611428565b505050565b6000818152600260205260409020546001600160a01b031680610a015760405162461bcd60e51b815260206004820152600a6024820152691393d517d3525395115160b21b60448201526064016104b7565b919050565b60006001600160a01b038216610a555760405162461bcd60e51b81526020600482015260146024820152736d696e7420746f207a65726f206164647265737360601b60448201526064016104b7565b6000600860008154610a6690611452565b91829055509050610a778382610de4565b6040516323b872dd60e01b81523360048201523060248201527f0000000000000000000000000000000000000000003b8e97d229a2d54800000060448201527f000000000000000000000000dc98c5543f3004debfaad8966ec403093d0aa4a86001600160a01b0316906323b872dd906064016020604051808303816000875af1158015610b09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2d91906113ee565b5092915050565b60006001600160a01b038216610b7b5760405162461bcd60e51b815260206004820152600c60248201526b5a45524f5f4144445245535360a01b60448201526064016104b7565b506001600160a01b031660009081526003602052604090205490565b600180546103b490611375565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b610c1b858585610592565b6001600160a01b0384163b1580610cb25750604051630a85bd0160e11b808252906001600160a01b0386169063150b7a0290610c639033908a90899089908990600401611479565b6020604051808303816000875af1158015610c82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ca6919061140b565b6001600160e01b031916145b610cce5760405162461bcd60e51b81526004016104b790611428565b5050505050565b606060078054610ce490611375565b80601f0160208091040260200160405190810160405280929190818152602001828054610d1090611375565b8015610d5d5780601f10610d3257610100808354040283529160200191610d5d565b820191906000526020600020905b815481529060010190602001808311610d4057829003601f168201915b50505050509050919050565b6006546001600160a01b03163314610d935760405162461bcd60e51b81526004016104b7906113af565b8051610da6906007906020840190610fbf565b507f562bf0237fa5139edc73ec903039c3a552e19ae62cc8292da62afeea43024b0a60076040516108cf91906114cd565b600780546103b490611375565b610dee8282610eb4565b6001600160a01b0382163b1580610e945750604051630a85bd0160e11b80825233600483015260006024830181905260448301849052608060648401526084830152906001600160a01b0384169063150b7a029060a4016020604051808303816000875af1158015610e64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e88919061140b565b6001600160e01b031916145b610eb05760405162461bcd60e51b81526004016104b790611428565b5050565b6001600160a01b038216610efe5760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b60448201526064016104b7565b6000818152600260205260409020546001600160a01b031615610f545760405162461bcd60e51b815260206004820152600e60248201526d1053149150511657d3525395115160921b60448201526064016104b7565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b828054610fcb90611375565b90600052602060002090601f016020900481019282610fed5760008555611033565b82601f1061100657805160ff1916838001178555611033565b82800160010185558215611033579182015b82811115611033578251825591602001919060010190611018565b5061103f929150611043565b5090565b5b8082111561103f5760008155600101611044565b6001600160e01b03198116811461106e57600080fd5b50565b60006020828403121561108357600080fd5b813561108e81611058565b9392505050565b600060208083528351808285015260005b818110156110c2578581018301518582016040015282016110a6565b818111156110d4576000604083870101525b50601f01601f1916929092016040019392505050565b6000602082840312156110fc57600080fd5b5035919050565b80356001600160a01b0381168114610a0157600080fd5b6000806040838503121561112d57600080fd5b61113683611103565b946020939093013593505050565b60006020828403121561115657600080fd5b61108e82611103565b60008060006060848603121561117457600080fd5b61117d84611103565b925061118b60208501611103565b9150604084013590509250925092565b801515811461106e57600080fd5b600080604083850312156111bc57600080fd5b6111c583611103565b915060208301356111d58161119b565b809150509250929050565b6000806000806000608086880312156111f857600080fd5b61120186611103565b945061120f60208701611103565b935060408601359250606086013567ffffffffffffffff8082111561123357600080fd5b818801915088601f83011261124757600080fd5b81358181111561125657600080fd5b89602082850101111561126857600080fd5b9699959850939650602001949392505050565b634e487b7160e01b600052604160045260246000fd5b6000602082840312156112a357600080fd5b813567ffffffffffffffff808211156112bb57600080fd5b818401915084601f8301126112cf57600080fd5b8135818111156112e1576112e161127b565b604051601f8201601f19908116603f011681019083821181831017156113095761130961127b565b8160405282815287602084870101111561132257600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000806040838503121561135557600080fd5b61135e83611103565b915061136c60208401611103565b90509250929050565b600181811c9082168061138957607f821691505b6020821081036113a957634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252600c908201526b15539055551213d49256915160a21b604082015260600190565b6000602082840312156113e757600080fd5b5051919050565b60006020828403121561140057600080fd5b815161108e8161119b565b60006020828403121561141d57600080fd5b815161108e81611058565b60208082526010908201526f155394d0519157d49150d2541251539560821b604082015260600190565b60006001820161147257634e487b7160e01b600052601160045260246000fd5b5060010190565b6001600160a01b038681168252851660208201526040810184905260806060820181905281018290526000828460a0840137600060a0848401015260a0601f19601f85011683010190509695505050505050565b600060208083526000845481600182811c9150808316806114ef57607f831692505b858310810361150c57634e487b7160e01b85526022600452602485fd5b878601838152602001818015611529576001811461153a57611565565b60ff19861682528782019650611565565b60008b81526020902060005b8681101561155f57815484820152908501908901611546565b83019750505b5094999850505050505050505056fea264697066735822122038ab4395b8dad511e4140f6365b1e6ed0743f2c86cd8e98c199cf79439eb3b6864736f6c634300080d0033

Verified Source Code Full Match

Compiler: v0.8.13+commit.abaa5c0e EVM: london Optimization: Yes (200 runs)
Owned.sol 44 lines
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Simple single owner authorization mixin.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Owned.sol)
abstract contract Owned {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event OwnerUpdated(address indexed user, address indexed newOwner);

    /*//////////////////////////////////////////////////////////////
                            OWNERSHIP STORAGE
    //////////////////////////////////////////////////////////////*/

    address public owner;

    modifier onlyOwner() virtual {
        require(msg.sender == owner, "UNAUTHORIZED");

        _;
    }

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

    constructor(address _owner) {
        owner = _owner;

        emit OwnerUpdated(address(0), _owner);
    }

    /*//////////////////////////////////////////////////////////////
                             OWNERSHIP LOGIC
    //////////////////////////////////////////////////////////////*/

    function setOwner(address newOwner) public virtual onlyOwner {
        owner = newOwner;

        emit OwnerUpdated(msg.sender, newOwner);
    }
}
Pebbles.sol 70 lines
// SPDX-License-Identifier: UNLICENSED

pragma solidity ^0.8.13;

import "solmate/tokens/ERC721.sol";
import "solmate/tokens/ERC20.sol";
import "solmate/auth/Owned.sol";

/**
 * @title Pebbles
 * @notice NFT wrapper for PebbleDAO's 72M entry requirement.
 * @author kvk0x
 */
contract PebbleNFT is ERC721, Owned {
    // Events

    event SetURI(string uri);
    event Withdraw(uint256 amount);

    // Config

    uint256 public immutable cost;
    ERC20 public immutable pebble;
    string public uri;

    // State

    uint256 public currentTokenId;

    // Constructor

    constructor(address _owner, ERC20 _pebble, uint256 _cost) ERC721("Pebbles", "PEBBLE") Owned(_owner) {
        pebble = _pebble;
        cost = _cost;
    }

    // Supply

    function mint(address to) external returns (uint256) {
        require(to != address(0), "mint to zero address");

        uint256 newItemId = ++currentTokenId;
        _safeMint(to, newItemId);

        pebble.transferFrom(msg.sender, address(this), cost);

        return newItemId;
    }

    // Metadata

    function tokenURI(uint256) public view virtual override returns (string memory) {
        return uri;
    }

    function setTokenURI(string memory _uri) external onlyOwner {
        uri = _uri;

        emit SetURI(uri);
    }

    // Admin

    function withdraw() external onlyOwner {
        uint256 balance = pebble.balanceOf(address(this));
        pebble.transfer(msg.sender, balance);

        emit Withdraw(balance);
    }
}
ERC721.sol 231 lines
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Modern, minimalist, and gas efficient ERC-721 implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol)
abstract contract ERC721 {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

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

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

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

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

    string public name;

    string public symbol;

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

    /*//////////////////////////////////////////////////////////////
                      ERC721 BALANCE/OWNER STORAGE
    //////////////////////////////////////////////////////////////*/

    mapping(uint256 => address) internal _ownerOf;

    mapping(address => uint256) internal _balanceOf;

    function ownerOf(uint256 id) public view virtual returns (address owner) {
        require((owner = _ownerOf[id]) != address(0), "NOT_MINTED");
    }

    function balanceOf(address owner) public view virtual returns (uint256) {
        require(owner != address(0), "ZERO_ADDRESS");

        return _balanceOf[owner];
    }

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

    mapping(uint256 => address) public getApproved;

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

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

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

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

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

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

        getApproved[id] = spender;

        emit Approval(owner, spender, id);
    }

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

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

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

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

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

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

            _balanceOf[to]++;
        }

        _ownerOf[id] = to;

        delete getApproved[id];

        emit Transfer(from, to, id);
    }

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

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

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

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

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

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

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

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

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

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

        _ownerOf[id] = to;

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

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

        require(owner != address(0), "NOT_MINTED");

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

        delete _ownerOf[id];

        delete getApproved[id];

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

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

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

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

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

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

/// @notice A generic interface for a contract which properly accepts ERC721 tokens.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol)
abstract contract ERC721TokenReceiver {
    function onERC721Received(
        address,
        address,
        uint256,
        bytes calldata
    ) external virtual returns (bytes4) {
        return ERC721TokenReceiver.onERC721Received.selector;
    }
}
ERC20.sol 206 lines
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol)
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
abstract contract ERC20 {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

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

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

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

    string public name;

    string public symbol;

    uint8 public immutable decimals;

    /*//////////////////////////////////////////////////////////////
                              ERC20 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 public totalSupply;

    mapping(address => uint256) public balanceOf;

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

    /*//////////////////////////////////////////////////////////////
                            EIP-2612 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 internal immutable INITIAL_CHAIN_ID;

    bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;

    mapping(address => uint256) public nonces;

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

    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals
    ) {
        name = _name;
        symbol = _symbol;
        decimals = _decimals;

        INITIAL_CHAIN_ID = block.chainid;
        INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
    }

    /*//////////////////////////////////////////////////////////////
                               ERC20 LOGIC
    //////////////////////////////////////////////////////////////*/

    function approve(address spender, uint256 amount) public virtual returns (bool) {
        allowance[msg.sender][spender] = amount;

        emit Approval(msg.sender, spender, amount);

        return true;
    }

    function transfer(address to, uint256 amount) public virtual returns (bool) {
        balanceOf[msg.sender] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(msg.sender, to, amount);

        return true;
    }

    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual returns (bool) {
        uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.

        if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;

        balanceOf[from] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(from, to, amount);

        return true;
    }

    /*//////////////////////////////////////////////////////////////
                             EIP-2612 LOGIC
    //////////////////////////////////////////////////////////////*/

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual {
        require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");

        // Unchecked because the only math done is incrementing
        // the owner's nonce which cannot realistically overflow.
        unchecked {
            address recoveredAddress = ecrecover(
                keccak256(
                    abi.encodePacked(
                        "\x19\x01",
                        DOMAIN_SEPARATOR(),
                        keccak256(
                            abi.encode(
                                keccak256(
                                    "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
                                ),
                                owner,
                                spender,
                                value,
                                nonces[owner]++,
                                deadline
                            )
                        )
                    )
                ),
                v,
                r,
                s
            );

            require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");

            allowance[recoveredAddress][spender] = value;
        }

        emit Approval(owner, spender, value);
    }

    function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
        return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
    }

    function computeDomainSeparator() internal view virtual returns (bytes32) {
        return
            keccak256(
                abi.encode(
                    keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
                    keccak256(bytes(name)),
                    keccak256("1"),
                    block.chainid,
                    address(this)
                )
            );
    }

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

    function _mint(address to, uint256 amount) internal virtual {
        totalSupply += amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

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

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

        // Cannot underflow because a user's balance
        // will never be larger than the total supply.
        unchecked {
            totalSupply -= amount;
        }

        emit Transfer(from, address(0), amount);
    }
}

Read Contract

balanceOf 0x70a08231 → uint256
cost 0x13faede6 → uint256
currentTokenId 0x009a9b7b → uint256
getApproved 0x081812fc → address
isApprovedForAll 0xe985e9c5 → bool
name 0x06fdde03 → string
owner 0x8da5cb5b → address
ownerOf 0x6352211e → address
pebble 0xfac9ac2e → address
supportsInterface 0x01ffc9a7 → bool
symbol 0x95d89b41 → string
tokenURI 0xc87b56dd → string
uri 0xeac989f8 → string

Write Contract 9 functions

These functions modify contract state and require a wallet transaction to execute.

approve 0x095ea7b3
address spender
uint256 id
mint 0x6a627842
address to
returns: uint256
safeTransferFrom 0x42842e0e
address from
address to
uint256 id
safeTransferFrom 0xb88d4fde
address from
address to
uint256 id
bytes data
setApprovalForAll 0xa22cb465
address operator
bool approved
setOwner 0x13af4035
address newOwner
setTokenURI 0xe0df5b6f
string _uri
transferFrom 0x23b872dd
address from
address to
uint256 id
withdraw 0x3ccfd60b
No parameters

Recent Transactions

This address has 1 on-chain transactions, but only 1.4% of the chain is indexed. Transactions will appear as indexing progresses. View on Etherscan →