GithubHelp home page GithubHelp logo

erc721a's Introduction

Docs NPM CI Issues MIT License Coverage

๐Ÿ“ข Version 4.x introduces several breaking changes. Please refer to the documentation for more details.

We highly recommend reading the migration guide, especially the part on supportsInterface if you are using with OpenZeppelin extensions (e.g. ERC2981).

About The Project

The goal of ERC721A is to provide a fully compliant implementation of IERC721 with significant gas savings for minting multiple NFTs in a single transaction. This project and implementation will be updated regularly and will continue to stay up to date with best practices.

The Azuki team created ERC721A for its sale on 1/12/22. There was significant demand for 8700 tokens made available to the public, and all were minted within minutes. The network BASEFEE remained low despite huge demand, resulting in low gas costs for minters, while minimizing network disruption for the wider ecosystem as well.

Gas Savings

For more information on how ERC721A works under the hood, please visit our blog. To find other projects that are using ERC721A, please visit erc721a.org and our curated projects list.

Chiru Labs is not liable for any outcomes as a result of using ERC721A. DYOR.

Docs

https://chiru-labs.github.io/ERC721A/

Upgradeable Version

https://github.com/chiru-labs/ERC721A-Upgradeable

Installation

npm install --save-dev erc721a

Usage

Once installed, you can use the contracts in the library by importing them:

pragma solidity ^0.8.4;

import "erc721a/contracts/ERC721A.sol";

contract Azuki is ERC721A {
    constructor() ERC721A("Azuki", "AZUKI") {}

    function mint(uint256 quantity) external payable {
        // `_mint`'s second argument now takes in a `quantity`, not a `tokenId`.
        _mint(msg.sender, quantity);
    }
}

Roadmap

  • Improve general repo and code quality (workflows, comments, etc.)
  • Add more documentation on benefits of using ERC721A
  • Maintain full test coverage

See the open issues for a full list of proposed features (and known issues).

Contributing

Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.

If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement".

Don't forget to give the project a star! Thanks again!

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit your Changes (git commit -m 'Add some AmazingFeature')
  4. Push to the Branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

Running tests locally

  1. npm install
  2. npm run test

License

Distributed under the MIT License. See LICENSE.txt for more information.

Contact

Project Link: https://github.com/chiru-labs/ERC721A

erc721a's People

Contributors

0xh3x avatar 0xinuarashi avatar 0xkerning avatar 0xmanga-eth avatar adilkhan012 avatar ahbanavi avatar alecpapierniak avatar alexfritzy avatar andreid avatar blankey1337 avatar caffeinum avatar chiru-labs avatar christian561 avatar cygaar avatar danipopes avatar dominikkeller avatar fulldecent avatar johnnyshankman avatar jorrsh avatar kamadefi avatar kyokosdream avatar lalanza808 avatar mirkopezo avatar missmetaversenft avatar nftley avatar vasinl124 avatar vectorized avatar willisk avatar zaventh avatar zestrells avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

erc721a's Issues

How to import ERC721A to remix?

image

This not working, how can i import it?

Also, if i mint one nft and transfer it another person on my opensea account it can be a problem for another mint?

Too many tokens!!!

Each owner is limited to owning 2^64 token as per uint64 balance in AddressData.

However, the _mint, _safeMint, _beforeTokenTransfers, _afterTokenTransfers functions all use the uint256 type which is too wide.

Those functions are all internal so perhaps narrowing the type is appropriate.

Hitting the Spurious Dragon limit

Hi. I'm learning ERC721 implementations now and I was going to adopt the ERC721A in my smart contract. So I updated my OZ-based implementation a bit to switch to the ERC721A. The issue I face is the contract size limit:

Warning: Contract code size exceeds 24576 bytes

I use Harhat, no other config parameters were changed, so my contract compiles just well with OZ, while failing to fit the size with ERC721A. My SC is fairly simple, just inheriting the base implementation and introducing a few additional variables and methods. Just about 200 lines including the blank lines and comments, so I didn't expect it to exceed the size. Any advice, please?

Disclaimer: I'm not a professional Solidity developer, so it can be just something on the very surface, but I don't see it.

Question: how to get n random number/simulate randomicity in ERC721A?

Our NFT can mint 1 of 6 different types. In a previous version, where ERC721 was used, and we only minted 1 at a time, I simulated a random number by using block time , block height, current token ID and a bunch of other numbers I had lying around, and took a mod 6.

But now, since minting n tokens is an atomic operation, all those numbers are essentially constant for the duration of the operation, meaning the user will mint n of the same token. Adding trivial behavior like rotation still allows the user to calculate which token they'd get.

I attempted to use Chainlink VRF V2 to receive random numbers. This made the operation extremely lengthy, expensive (both gas and Link), and worse unpredictable (nearly 7 minutes on Rinkeby) and dependent on a callback function from the Chainlink Oracle.

How can I allow a user who's minting n token to get n different ones? Is anyone out there relying on random outcome using ERC721A?
Ideas are welcome.

OpenSea not showing all Tokens

Hey there,

Not even sure if this is an issue of the ERC721A, but once i moved from ERC721enumerable to ERC721A after deploying on Rinkeby and minting a few tokens. I don't see all tokens listed. I noticed that i only see as many tokens as owners. Even when i look in the profile collected of an address that minted 3 i only see 1 token.

Is there something extra we have to do with ERC721A and OpenSea to have it show all tokens?

thanks in advance.

Compile Issue

I keep getting the following error when using remix to create my cotract:

        DeclarationError: Undeclared identifier.

--> contracts/DAL.sol:95:31:
|
95 | ownerIds[index] = tokenOfOwnerByIndex(_owner, index);
| ^^^^^^^^^^^^^^^^^^^

Although it is identified in both IERC721.sol and IERC721Enumerable.sol

Any ideas?

Thanks

What is the best way to transfer ownership?

Is it okay to use transfer ownership method from contract? I have a customer who wants to sell nft's he wants to be owner of the contract. What are the things I should pay attention to when transferring? While people start minting nfts, is any problem in any chance will appear?

Move IERC721Enumerable impl to an extension

I don't think everyone needs this on-chain, and considering the risks of DOS related to an O(totalSupply) method (tokenOfOwnerByIndex), I do think it'd make a lot of sense to have this implemented in an extension.

Error handling

Can someone explain why the errors don't have comments above them? Wouldn't that make them more effective in explaining the error? Is this direction, to cut comments, for gas savings?

error ApprovalCallerNotOwnerNorApproved();
error ApprovalQueryForNonexistentToken();
error ApproveToCaller();
error ApprovalToCurrentOwner();
error BalanceQueryForZeroAddress();
error MintedQueryForZeroAddress();
error BurnedQueryForZeroAddress();
error MintToZeroAddress();
error MintZeroQuantity();
error OwnerIndexOutOfBounds();
error OwnerQueryForNonexistentToken();
error TokenIndexOutOfBounds();
error TransferCallerNotOwnerNorApproved();
error TransferFromIncorrectOwner();
error TransferToNonERC721ReceiverImplementer();
error TransferToZeroAddress();
error URIQueryForNonexistentToken();

Possible to use custom TokenURI for each token mapping?

I want to set tokenURI for each tokenbatch. Would that be possible here?. If yes, can you please direct?.. I could see the currentIndex to track the tokenId, but how do I set this tokenURI for the respective TokenBatch.

For instance, 1-10 => one tokenURI
11 => Another uri
12.- 15 => different tokenURI

Any thoughts?

Gas fees very high on safeTransfer Method

I minted 310 tokens at a single transaction.
Eg: 0 to 310

Safetransfering Token ID is around $8
Safetransfering Token ID 300 is around $300

Wonder whats caused the price change for high index tokens.

This only happens for higher transactions

walletOfOwner tokenids problem

I trying to use ERC721A with openzeppelin contracts and also hashlips repository. I replaced ERC721Enumarable with ERC721A and then im facing with one problem. Check out below.

image

how can i use this with ERC721A?

Totalsupply() decrements when token id is burned (HUGE ISSUE)

require(totalSupply() + _mintAmount <= maxSupply, 'Max supply exceeded!');
using this modifier will cause you to suffer a small issue which his
if a user burns his token id total supply decrements
causing users to mint extra nfts after your max supply
this is a huge issue I noticed even in azukis contract

_setOwnersExplicit is not used

_setOwnersExplicit has internal visibility, but is never called. I understand this could still be useful for implementations extending ERC721A, however, the current contract can be used as-is and this function is effectively just wasting gas in its current state.

I think it would make sense to either remove it entirely or add it as an optional extension. Or even possibly add an external function that does nothing other than call _setOwnersExplicit.

Comments on ERC721A

I'd like to start off by thanking you for working on this and allowing contributions from the community.

Here are some of my comments on the current implementation and what I personally would change.

  1. Remove maxBatchSize_ in constructor
  • keeps implementation as close as possible to the original
  • allows max batch logic to be implemented in inheriting class, just like before
  • as I see it, there is no need for ERC721A to know the max batch size

image

...

image

  1. Add functionality for starting index to be either 0 or 1 (this has been discussed).
  • even though I believe they should simply start at 0, some libraries like hashlips require them to start at 1 by default. That's why it would be nice to have an easy way of switching this in the contract
  1. Add _mint alongside _safeMint (and perhaps advocate this as the standard).
  • currently _safeMint checks that caller is a ERC721Receiver n times in a loop
  • this adds unnecessary checks, as the standard seems to be to disallow minting from contracts

image

  • also added a require for quantity to be > 0, as otherwise someone could technically be added as an owner (at least temporarily), even though the counter doesn't increase

Other than that, I'm not sure how I feel about supporting the IEC721Enumerable interface, if the functionality is added by inefficient loops that should never be called on-chain. I don't see much point in tokenOfOwnerByIndex at all (it has it's use-case in ERC721Enumerable). Why not replace that with something actually useful, such as listing all tokenIds of an owner (though this could also be considered for an extension).

image

A last note on 1:
I did actually see a case being made for adding the maximum collection size into ERC721A, because otherwise the inheriting contract will need to read from the chain (get totalSupply and make sure it's below max collections size), as opposed to the mint function handling this for no extra read cost (totalSupply is already present).

I haven't submitted a pull request yet, because I would like to see some reactions to this first.

Is it safe to use estimateGas on _safeMint function?

First of all thanks for this amazing contract (@chiru-labs and all other contributors)

According to web3.js documentation; we can estimate gas with estimateGas function. But this calculation can be misleading if a function can cost different at different contract states.

(https://web3js.readthedocs.io/en/v1.2.11/web3-eth-contract.html#methods-mymethod-estimategas)

My question is, is _safeMint function can consume more gas according to contract's state? (with same token count to same wallet)

feat: `_totalMinted()` function.

With the burn feature, collections will need to check against _currentIndex if they want to limit the total number of mints.
Checking against totalSupply() can result in new mints being possible if someone burns their token(s).

With upcoming PR #66, users will have to check against _currentIndex - _startTokenId() instead.

This can cause some confusion.

I suggest adding an internal _totalMinted() function,
and update the README to encourage checking against _totalMinted() instead.

Another option is to put this into #66.

Let me know your comments.

If you want to make a PR for this issue, please feel free to do so. Drop a comment below too.

Otherwise, I will probably wait a few / several days after #66 is merged before starting a PR for this (if this feature is not in a PR or merged by then).

@cygaar @ahbanavi

Question: getting all tokens by address

I would like to get all the tokens owned by a user (address). I see that he main contract imports IERC721Enumerable.sol but does not implement all of its functions (specifically tokenOfOwnerByIndex). Is there an easy way to implement this, based on the data the token maintains already?

One of the other things I thought of doing is emitting a Minted(address, quantity, startIndex, endIndex) event at the end of my mint function, and I assume I can later query for those events, but I'd much rather see if I can get these programmatically.

Thanks!

Inconsistent mint ID's

I'm testing this code as a replacement from the Openzeppelin implementation and having issues.

If I mint 1 nft with the mint function it works fine on first trigger.. But subsequent mints (Remix) the batches are odd and we end up with three nfts minted even though I only put 1 in the mint function.

Then when adding 3 mints, it minted 14? This is when viewing maxSupply read function. This seems off but can't imagine why:

{ "uint256 _mintAmount": "1" }

[{"logIndex":1,"blockNumber":47,"blockHash":"0x1a8884d8bec9c019688b85569151c9a92c01b7b038d6ab1da92fbec1ab62f374","transactionHash":"0x2d740ad7f51a046636c6909de0ad80ee22baba360b69c9696544c871f9424e2a","transactionIndex":0,"address":"0xDA07165D4f7c84EEEfa7a4Ff439e039B7925d3dF","data":"0x","topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000005b38da6a701c568545dcfcb03fcb875f56beddc4","0x0000000000000000000000000000000000000000000000000000000000000004"],"id":"log_d7432cc2"},{"logIndex":1,"blockNumber":47,"blockHash":"0x1a8884d8bec9c019688b85569151c9a92c01b7b038d6ab1da92fbec1ab62f374","transactionHash":"0x2d740ad7f51a046636c6909de0ad80ee22baba360b69c9696544c871f9424e2a","transactionIndex":0,"address":"0xDA07165D4f7c84EEEfa7a4Ff439e039B7925d3dF","data":"0x","topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000005b38da6a701c568545dcfcb03fcb875f56beddc4","0x0000000000000000000000000000000000000000000000000000000000000005"],"id":"log_d7432cc2"},{"logIndex":1,"blockNumber":47,"blockHash":"0x1a8884d8bec9c019688b85569151c9a92c01b7b038d6ab1da92fbec1ab62f374","transactionHash":"0x2d740ad7f51a046636c6909de0ad80ee22baba360b69c9696544c871f9424e2a","transactionIndex":0,"address":"0xDA07165D4f7c84EEEfa7a4Ff439e039B7925d3dF","data":"0x","topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000005b38da6a701c568545dcfcb03fcb875f56beddc4","0x0000000000000000000000000000000000000000000000000000000000000006"],"id":"log_d7432cc2"},{"logIndex":1,"blockNumber":47,"blockHash":"0x1a8884d8bec9c019688b85569151c9a92c01b7b038d6ab1da92fbec1ab62f374","transactionHash":"0x2d740ad7f51a046636c6909de0ad80ee22baba360b69c9696544c871f9424e2a","transactionIndex":0,"address":"0xDA07165D4f7c84EEEfa7a4Ff439e039B7925d3dF","data":"0x","topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000005b38da6a701c568545dcfcb03fcb875f56beddc4","0x0000000000000000000000000000000000000000000000000000000000000007"],"id":"log_d7432cc2"},{"logIndex":1,"blockNumber":47,"blockHash":"0x1a8884d8bec9c019688b85569151c9a92c01b7b038d6ab1da92fbec1ab62f374","transactionHash":"0x2d740ad7f51a046636c6909de0ad80ee22baba360b69c9696544c871f9424e2a","transactionIndex":0,"address":"0xDA07165D4f7c84EEEfa7a4Ff439e039B7925d3dF","data":"0x","topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000005b38da6a701c568545dcfcb03fcb875f56beddc4","0x0000000000000000000000000000000000000000000000000000000000000008"],"id":"log_d7432cc2"},{"logIndex":1,"blockNumber":47,"blockHash":"0x1a8884d8bec9c019688b85569151c9a92c01b7b038d6ab1da92fbec1ab62f374","transactionHash":"0x2d740ad7f51a046636c6909de0ad80ee22baba360b69c9696544c871f9424e2a","transactionIndex":0,"address":"0xDA07165D4f7c84EEEfa7a4Ff439e039B7925d3dF","data":"0x","topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000005b38da6a701c568545dcfcb03fcb875f56beddc4","0x0000000000000000000000000000000000000000000000000000000000000009"],"id":"log_d7432cc2"},{"logIndex":1,"blockNumber":47,"blockHash":"0x1a8884d8bec9c019688b85569151c9a92c01b7b038d6ab1da92fbec1ab62f374","transactionHash":"0x2d740ad7f51a046636c6909de0ad80ee22baba360b69c9696544c871f9424e2a","transactionIndex":0,"address":"0xDA07165D4f7c84EEEfa7a4Ff439e039B7925d3dF","data":"0x","topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000005b38da6a701c568545dcfcb03fcb875f56beddc4","0x000000000000000000000000000000000000000000000000000000000000000a"],"id":"log_d7432cc2"},{"logIndex":1,"blockNumber":47,"blockHash":"0x1a8884d8bec9c019688b85569151c9a92c01b7b038d6ab1da92fbec1ab62f374","transactionHash":"0x2d740ad7f51a046636c6909de0ad80ee22baba360b69c9696544c871f9424e2a","transactionIndex":0,"address":"0xDA07165D4f7c84EEEfa7a4Ff439e039B7925d3dF","data":"0x","topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000005b38da6a701c568545dcfcb03fcb875f56beddc4","0x000000000000000000000000000000000000000000000000000000000000000b"],"id":"log_d7432cc2"},{"logIndex":1,"blockNumber":47,"blockHash":"0x1a8884d8bec9c019688b85569151c9a92c01b7b038d6ab1da92fbec1ab62f374","transactionHash":"0x2d740ad7f51a046636c6909de0ad80ee22baba360b69c9696544c871f9424e2a","transactionIndex":0,"address":"0xDA07165D4f7c84EEEfa7a4Ff439e039B7925d3dF","data":"0x","topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000005b38da6a701c568545dcfcb03fcb875f56beddc4","0x000000000000000000000000000000000000000000000000000000000000000c"],"id":"log_d7432cc2"}]

Unable to stake using ERC-721A?

Hello, first of all let me congratulate the Chiru Labs team for their innovative change which led to the current 721A contract, that was really well thought!

So I am developing a project and wanted to integrate 721A with it. As a part of the roadmap, we want to enable users to stake their tokens. To do this, we are doing the following:

  • Using a "stake.sol" contract to handle all the staking. In this contract, we call a function "stakingTokens", that will check all the conditions prior to staking (if the user is the owner of the token, if the token isn't already staked, etcโ€ฆ). After checking all the conditions, we call the "transferFrom" function of the ERC-721A contract and send the usual parameters "msg.sender", "address(this)", "_tokenIds".
  • The issue starts now. In line 409 when the "_transfer" function of the 721A checks if "isApprovedOrOwner". The problem is, the "msg.sender" address will belong to the contract that is calling "_transfer" (which will be the address of "stake.sol"), and not to the actual owner. This will raise an error, making it unable to stake the tokens.

Are we missing something? Our staking used to work when we were using ERC-721, but stopped working when we integrated ERC-721A.

image

Add OpenSea Whitelisting

From OpenSea docs:

The ERC721Tradable and ERC1155Tradable contracts whitelist the proxy accounts of OpenSea users so that they are automatically able to trade any item on OpenSea (without having to pay gas for an additional approval). On OpenSea, each user has a "proxy" account that they control, and is ultimately called by the marketplace contracts to trade their items.

This will save a lot of gas, should definitely be added, and is not very difficult to add.

Add "virtual" to override transferFrom & safeTransferFrom

Will it be compatible to override and add "virtual" on transferFrom & safeTransferFrom, to be overridden in the inheritted contract? I'd like to implement future-compatible interface for token yield on transfer function. Please advice. Thanks!

// BEFORE
function transferFrom(
    address from,
    address to,
    uint256 tokenId
) public override {
    _transfer(from, to, tokenId);
}

// AFTER
function transferFrom(
    address from,
    address to,
    uint256 tokenId
) public virtual override {
    _transfer(from, to, tokenId);
}

// USAGE
function transferFrom(address from_, address to_, uint256 tokenId_) public override nonReentrant {
    if (yieldToken != iYield(address(0x0))) {
        yieldToken.updateReward(from_, to_, tokenId_);
    }
    ERC721A.transferFrom(from_, to_, tokenId_);
}

TokenOwnership.startTimestamp declared, but never used !!!

Hi all,

I guess we can just remove TokenOwnership structure and change the _ownerships variable type to a simple mapping(uint256 => address), however I don't know if is there any benefit for the startTimestamp in the TokenOwnership.

I believe this way we can reduce the gas usage a bit more.

Possible reentrancy issues in _mint() function?

Hi, I'm looking to implement ERC721A in a project so have been combing through the code. Still new to reentrancy patterns so wanted to ask the question first before submitting a PR.

When calling _safeMint(), control is handed off to a receiving contract before totalSupply is updated. Could a malicious contract create an exploit or wreck havoc by re-entering the mint function from here? In the re-entrant call, startTokenId would be identical to the original call, but balances changed and events have been emitted so it's not entirely obvious to me what kind of damage could occur.

Code in question:

uint256 startTokenId = _currentIndex;
...
unchecked {
    _addressData[to].balance += uint128(quantity);
    _addressData[to].numberMinted += uint128(quantity);

    _ownerships[startTokenId].addr = to;
    _ownerships[startTokenId].startTimestamp = uint64(block.timestamp);

    uint256 updatedIndex = startTokenId;

    for (uint256 i; i < quantity; i++) {
        emit Transfer(address(0), to, updatedIndex);
        if (safe && !_checkOnERC721Received(address(0), to, updatedIndex, _data)) {
            revert TransferToNonERC721ReceiverImplementer();
        }

        updatedIndex++;
    }

    _currentIndex = updatedIndex;
}

Batch Size Inquiry

The concept of minting in defined batches is interesting - but that brings the question - is their an optimal batch size where different gas savings are seen and say a batch size was initiated at 1. Wouldn't that defeat the purpose of the optimization - and if so should we be adding a check to prevent a batch size of one?

Suggestion: add contract version

It would be a good idea to add the release version on top of the contracts/ERC721A.sol file and update it when a new version releases.
Some devs or savvy people would like to know what version of ERC721A the implemented contract uses.

// SPDX-License-Identifier: MIT
// ERC721A v2.2.0
// Creator: Chiru Labs
.
.
.

About `tokensOfOwner` function

tokensOfOwner function is definitely quite useful for small capped collections
(probably > 90% of the collections you see these days).

/// @dev Returns the tokenIds of the address. O(totalSupply) in complexity.
function tokensOfOwner(address owner) external view returns (uint256[] memory) {
    unchecked {
        uint256[] memory a = new uint256[](balanceOf(owner)); 
        uint256 end = _currentIndex;
        uint256 tokenIdsIdx;
        address currOwnershipAddr;
        for (uint256 i; i < end; i++) {
            TokenOwnership memory ownership = _ownerships[i];
            if (ownership.burned) {
                continue;
            }
            if (ownership.addr != address(0)) {
                currOwnershipAddr = ownership.addr;
            }
            if (currOwnershipAddr == owner) {
                a[tokenIdsIdx++] = i;
            }
        }
        return a;    
    }
}

However, we have to consider the implications of including a O(totalSupply) function in the main library. Even if we know if it supports collections of 10,000 unique items, it is still probable that someone will use this function for a collection of say 100,000 unique items, and result in off-chain queries from Infura (Metamask) / Alchemy failing.

Even if we include a cautionary comment, someone might just not read it and use the function without understanding the caveats.

One possible way to provide users convenience, but still keep the main library general is to include this in an examples folder, instead of an extension.

Let me know what you think.

@fulldecent @cygaar

Related:

Starting from 0

I'm using erc721a for my contract but it starting from 0 and i have no 0.json on my ipfs ):

My contract is simple please check it out below.

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

import "https://github.com/chiru-labs/ERC721A/blob/main/contracts/ERC721A.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract NEWNFTT is Ownable, ERC721A {
  using Strings for uint256;

  string public baseURI;
  string public baseExtension = ".json";
  uint256 public cost = 200000000000000000;
  uint256 public maxSupply = 10000;
  uint256 public maxMintAmount = 3;

  constructor() ERC721A("Name", "SYMBOL") {
    setBaseURI("ipfs://ipfslink/");
  }

  // internal
  function _baseURI() internal view virtual override returns (string memory) {
    return baseURI;
  }

  // public
  function mint(uint256 _mintAmount) public payable {
    uint256 supply = totalSupply();
    require(_mintAmount > 0, "need to mint at least 1 NFT");
    require(_mintAmount <= maxMintAmount, "max mint amount per session exceeded");
    require(supply + _mintAmount <= maxSupply, "max NFT limit exceeded");

    if (msg.sender != owner()) {
        require(msg.value >= cost * _mintAmount, "insufficient funds");
    }

    _safeMint(msg.sender, _mintAmount);
  }
  
  function tokenURI(uint256 tokenId)
    public
    view
    virtual
    override
    returns (string memory)
  {
    require(
      _exists(tokenId),
      "ERC721Metadata: URI query for nonexistent token"
    );

    string memory currentBaseURI = _baseURI();
    return bytes(currentBaseURI).length > 0
        ? string(abi.encodePacked(currentBaseURI, tokenId.toString(), baseExtension))
        : "";
  }
  
  function setCost(uint256 _newCost) public onlyOwner {
    cost = _newCost;
  }

  function setmaxMintAmount(uint256 _newmaxMintAmount) public onlyOwner {
    maxMintAmount = _newmaxMintAmount;
  }

  function setBaseURI(string memory _newBaseURI) public onlyOwner {
    baseURI = _newBaseURI;
  }

  function setBaseExtension(string memory _newBaseExtension) public onlyOwner {
    baseExtension = _newBaseExtension;
  }
  
  function withdraw() public payable onlyOwner {
    // =============================================================================
    (bool os, ) = payable(owner()).call{value: address(this).balance}("");
    require(os);
    // =============================================================================
  }
}

When i mint 1 NFT my URI is
image

tokenURI returns empty string everytime

//Contract based on [https://docs.openzeppelin.com/contracts/3.x/erc721](https://docs.openzeppelin.com/contracts/3.x/erc721)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import "erc721a/contracts/ERC721A.sol";

contract MyNFT is ERC721A {

    constructor() ERC721A("MyNFT", "MNFT") {}

  function mint(uint256 quantity, bytes memory tokenUri) external payable {
    // _safeMint's second argument now takes in a quantity, not a tokenId.
    _safeMint(msg.sender, quantity, tokenUri);
  }
}

Even the transaction was successful after calling mint() method, but the tokenURI() returns empty string every time. When I import the nft my wallet it does not preview the image.

The nft meta data is: https://gateway.pinata.cloud/ipfs/QmYcmYEkkr6fPCQUV2Vss8cFYYQm4CQiYCZudahNHnqp7G

feat: add hardhat scripts for benchmarking the gas consumption

adding scripts to calculate the gas for ERC721A use cases should be beneficial for the project long term roadmap.

with scripts as a source of truth, we would be able to track and check the gas for multiple cases ( mint, transfer..etc)

if the community agree on using hardhat script as gas estimation i can add those scripts

Aux uint64 packing

Our team is looking to also store two booleans in addition to the number of whitelist mint slots remaining.

I know Solidity bool takes 1 byte, but can be represented with a single bit in theory. Should I use bitwise operations to encode these in the last two bits of the uint64 or the last two bytes?

Or would a better path to be to just remove the uint64 aux and replace it with multiple smaller memory variables that fit the same slot?

Our whitelist slots will never be that large of a number, to be honest, likely a single digit integer. In this case, according to strategy in the last paragraph, would it be better to just store a uint8 (1 byte) and 2 bools (2 bytes) and they will be packed into the Ownership struct the same way as currently exists in the repo?

Thanks for your help!

Redundant _ownershipOf call in ERC721ABurnable

๐Ÿง Problem

Right now, there is a _ownershipOf call in ERC721ABurnable:

function burn(uint256 tokenId) public virtual {
TokenOwnership memory prevOwnership = _ownershipOf(tokenId);

And another in internal _burn function:
function _burn(uint256 tokenId) internal virtual {
TokenOwnership memory prevOwnership = _ownershipOf(tokenId);

๐Ÿค” Possible Fix

We can eliminate the first _ownershipOf call by adding an extra boolean approvalCheck argument in the internal _burn function:

function _burn(uint256 tokenId, bool approvalCheck) internal virtual {
      TokenOwnership memory prevOwnership = ownershipOf(tokenId);

      if (approvalCheck){
          bool isApprovedOrOwner = (_msgSender() == prevOwnership.addr ||
              isApprovedForAll(prevOwnership.addr, _msgSender()) ||
              getApproved(tokenId) == _msgSender());

          if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
      }

      _beforeTokenTransfers(prevOwnership.addr, address(0), tokenId, 1);
     .
     .
     .

And use it in ERC721ABurnable public burn function like this:

function burn(uint256 tokenId) public virtual {
    _burn(tokenId, true);
}

๐Ÿ“ Drawbacks

With the above approach, the internal _burn function:

  1. Is NOT compatible with OpenZeppelin _burn function anymore,
  2. NOT backwards compatible with ERC721A itself.

IMO, the first one is OK, I mean the only reason that ERC721A is existed, is to be more gas efficient than other contracts.
And about the second, the main branch is already not backwards compatible with v3.0.0 after #161.

Anyway, a possible fix for both drawbacks is adding a wrapper for _burn with only tokenId argument:

function _burn(uint256 tokenId) internal virtual {
    _burn(tokenId, false);
}

โ›ฝ Gas Reports

Before changes
ยท---------------------------------------------------------------|---------------------------|-------------|-----------------------------ยท
|                     Solc version: 0.8.11                      ยท  Optimizer enabled: true  ยท  Runs: 800  ยท  Block limit: 30000000 gas  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  Methods                                                                                                                              โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  Contract                               ยท  Method             ยท  Min        ยท  Max        ยท  Avg        ยท  # calls      ยท  usd (avg)  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721ABurnableMock                    ยท  approve            ยท      30839  ยท      50979  ยท      40909  ยท            2  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721ABurnableMock                    ยท  burn               ยท      49049  ยท     117422  ยท      96936  ยท           25  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721ABurnableMock                    ยท  safeMint           ยท          -  ยท          -  ยท     111170  ยท           15  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721ABurnableMock                    ยท  setApprovalForAll  ยท      26277  ยท      46189  ยท      36233  ยท            2  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721ABurnableMock                    ยท  transferFrom       ยท      86680  ยท      92867  ยท      89774  ยท            2  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721ABurnableOwnersExplicitMock      ยท  burn               ยท      66137  ยท      89294  ยท      77716  ยท            2  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721ABurnableOwnersExplicitMock      ยท  safeMint           ยท      78346  ยท      93494  ยท      84054  ยท            3  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721ABurnableOwnersExplicitMock      ยท  setOwnersExplicit  ยท          -  ยท          -  ยท      81199  ยท            1  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721ABurnableStartTokenIdMock        ยท  approve            ยท      30851  ยท      50991  ยท      40921  ยท            2  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721ABurnableStartTokenIdMock        ยท  burn               ยท      49095  ยท     114711  ยท      94444  ยท           26  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721ABurnableStartTokenIdMock        ยท  safeMint           ยท          -  ยท          -  ยท      94048  ยท           15  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721ABurnableStartTokenIdMock        ยท  setApprovalForAll  ยท      26255  ยท      46167  ยท      36211  ยท            2  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721ABurnableStartTokenIdMock        ยท  transferFrom       ยท      86692  ยท      90501  ยท      88597  ยท            2  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AGasReporterMock                 ยท  mintOne            ยท      56462  ยท      90662  ยท      57146  ยท           50  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AGasReporterMock                 ยท  mintTen            ยท      74116  ยท     108316  ยท      74800  ยท           50  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AGasReporterMock                 ยท  safeMintOne        ยท      59143  ยท      93343  ยท      59827  ยท           50  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AGasReporterMock                 ยท  safeMintTen        ยท      76775  ยท     110975  ยท      77459  ยท           50  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AMock                            ยท  approve            ยท          -  ยท          -  ยท      50933  ยท            1  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AMock                            ยท  mint               ยท      91770  ยท      99626  ยท      97531  ยท           15  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AMock                            ยท  safeMint           ยท      78336  ยท     123103  ยท      88216  ยท          113  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AMock                            ยท  safeTransferFrom   ยท      93735  ยท      93747  ยท      93744  ยท            9  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AMock                            ยท  setApprovalForAll  ยท      46185  ยท      46197  ยท      46196  ยท           17  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AMock                            ยท  setAux             ยท      27242  ยท      44426  ยท      32970  ยท            3  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AMock                            ยท  transferFrom       ยท      86646  ยท      86658  ยท      86656  ยท            7  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AOwnersExplicitMock              ยท  safeMint           ยท      78346  ยท      93494  ยท      84054  ยท           21  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AOwnersExplicitMock              ยท  setOwnersExplicit  ยท      48337  ยท     124293  ยท      84934  ยท            8  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AOwnersExplicitStartTokenIdMock  ยท  safeMint           ยท      76372  ยท      80300  ยท      78332  ยท           21  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AOwnersExplicitStartTokenIdMock  ยท  setOwnersExplicit  ยท      48346  ยท     124404  ยท      84999  ยท            8  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AStartTokenIdMock                ยท  approve            ยท          -  ยท          -  ยท      50957  ยท            1  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AStartTokenIdMock                ยท  mint               ยท      74702  ยท      82570  ยท      80473  ยท           15  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AStartTokenIdMock                ยท  safeMint           ยท      76429  ยท     106048  ยท      81148  ยท          113  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AStartTokenIdMock                ยท  safeTransferFrom   ยท      93747  ยท      93759  ยท      93755  ยท            9  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AStartTokenIdMock                ยท  setApprovalForAll  ยท      46163  ยท      46175  ยท      46174  ยท           17  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AStartTokenIdMock                ยท  setAux             ยท      27220  ยท      44404  ยท      32948  ยท            3  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AStartTokenIdMock                ยท  transferFrom       ยท          -  ยท          -  ยท      86736  ยท            7  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  Deployments                                                  ยท                                         ยท  % of limit   ยท             โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721ABurnableMock                                          ยท          -  ยท          -  ยท    1319981  ยท        4.4 %  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721ABurnableOwnersExplicitMock                            ยท          -  ยท          -  ยท    1399406  ยท        4.7 %  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721ABurnableStartTokenIdMock                              ยท          -  ยท          -  ยท    1388094  ยท        4.6 %  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AGasReporterMock                                       ยท          -  ยท          -  ยท    1170730  ยท        3.9 %  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AMock                                                  ยท          -  ยท          -  ยท    1340833  ยท        4.5 %  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AOwnersExplicitMock                                    ยท          -  ยท          -  ยท    1255001  ยท        4.2 %  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AOwnersExplicitStartTokenIdMock                        ยท          -  ยท          -  ยท    1329560  ยท        4.4 %  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AStartTokenIdMock                                      ยท          -  ยท          -  ยท    1405490  ยท        4.7 %  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721ReceiverMock                                           ยท          -  ยท          -  ยท     207526  ยท        0.7 %  ยท          -  โ”‚
ยท---------------------------------------------------------------|-------------|-------------|-------------|---------------|-------------ยท
After adding approvalCheck argument in _burn and removing ERC721ABurnable redundant call
ยท---------------------------------------------------------------|---------------------------|-------------|-----------------------------ยท
|                     Solc version: 0.8.11                      ยท  Optimizer enabled: true  ยท  Runs: 800  ยท  Block limit: 30000000 gas  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  Methods                                                                                                                              โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  Contract                               ยท  Method             ยท  Min        ยท  Max        ยท  Avg        ยท  # calls      ยท  usd (avg)  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721ABurnableMock                    ยท  approve            ยท      30839  ยท      50979  ยท      40909  ยท            2  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721ABurnableMock                    ยท  burn               ยท      48419  ยท     114911  ยท      95133  ยท           25  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721ABurnableMock                    ยท  safeMint           ยท          -  ยท          -  ยท     111170  ยท           15  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721ABurnableMock                    ยท  setApprovalForAll  ยท      26277  ยท      46189  ยท      36233  ยท            2  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721ABurnableMock                    ยท  transferFrom       ยท      86680  ยท      92867  ยท      89774  ยท            2  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721ABurnableOwnersExplicitMock      ยท  burn               ยท      65507  ยท      88298  ยท      76903  ยท            2  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721ABurnableOwnersExplicitMock      ยท  safeMint           ยท      78346  ยท      93494  ยท      84054  ยท            3  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721ABurnableOwnersExplicitMock      ยท  setOwnersExplicit  ยท          -  ยท          -  ยท      81199  ยท            1  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721ABurnableStartTokenIdMock        ยท  approve            ยท      30851  ยท      50991  ยท      40921  ยท            2  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721ABurnableStartTokenIdMock        ยท  burn               ยท      48431  ยท     112544  ยท      92855  ยท           26  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721ABurnableStartTokenIdMock        ยท  safeMint           ยท          -  ยท          -  ยท      94048  ยท           15  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721ABurnableStartTokenIdMock        ยท  setApprovalForAll  ยท      26255  ยท      46167  ยท      36211  ยท            2  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721ABurnableStartTokenIdMock        ยท  transferFrom       ยท      86692  ยท      90501  ยท      88597  ยท            2  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AGasReporterMock                 ยท  mintOne            ยท      56462  ยท      90662  ยท      57146  ยท           50  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AGasReporterMock                 ยท  mintTen            ยท      74116  ยท     108316  ยท      74800  ยท           50  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AGasReporterMock                 ยท  safeMintOne        ยท      59143  ยท      93343  ยท      59827  ยท           50  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AGasReporterMock                 ยท  safeMintTen        ยท      76775  ยท     110975  ยท      77459  ยท           50  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AMock                            ยท  approve            ยท          -  ยท          -  ยท      50933  ยท            1  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AMock                            ยท  mint               ยท      91770  ยท      99626  ยท      97531  ยท           15  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AMock                            ยท  safeMint           ยท      78336  ยท     123103  ยท      88216  ยท          113  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AMock                            ยท  safeTransferFrom   ยท      93735  ยท      93747  ยท      93744  ยท            9  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AMock                            ยท  setApprovalForAll  ยท      46185  ยท      46197  ยท      46196  ยท           17  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AMock                            ยท  setAux             ยท      27242  ยท      44426  ยท      32970  ยท            3  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AMock                            ยท  transferFrom       ยท      86646  ยท      86658  ยท      86656  ยท            7  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AOwnersExplicitMock              ยท  safeMint           ยท      78346  ยท      93494  ยท      84054  ยท           21  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AOwnersExplicitMock              ยท  setOwnersExplicit  ยท      48337  ยท     124293  ยท      84934  ยท            8  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AOwnersExplicitStartTokenIdMock  ยท  safeMint           ยท      76372  ยท      80300  ยท      78332  ยท           21  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AOwnersExplicitStartTokenIdMock  ยท  setOwnersExplicit  ยท      48346  ยท     124404  ยท      84999  ยท            8  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AStartTokenIdMock                ยท  approve            ยท          -  ยท          -  ยท      50957  ยท            1  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AStartTokenIdMock                ยท  mint               ยท      74702  ยท      82570  ยท      80473  ยท           15  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AStartTokenIdMock                ยท  safeMint           ยท      76429  ยท     106048  ยท      81148  ยท          113  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AStartTokenIdMock                ยท  safeTransferFrom   ยท      93747  ยท      93759  ยท      93755  ยท            9  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AStartTokenIdMock                ยท  setApprovalForAll  ยท      46163  ยท      46175  ยท      46174  ยท           17  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AStartTokenIdMock                ยท  setAux             ยท      27220  ยท      44404  ยท      32948  ยท            3  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AStartTokenIdMock                ยท  transferFrom       ยท          -  ยท          -  ยท      86736  ยท            7  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  Deployments                                                  ยท                                         ยท  % of limit   ยท             โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721ABurnableMock                                          ยท          -  ยท          -  ยท    1319357  ยท        4.4 %  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721ABurnableOwnersExplicitMock                            ยท          -  ยท          -  ยท    1398770  ยท        4.7 %  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721ABurnableStartTokenIdMock                              ยท          -  ยท          -  ยท    1387446  ยท        4.6 %  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AGasReporterMock                                       ยท          -  ยท          -  ยท    1170730  ยท        3.9 %  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AMock                                                  ยท          -  ยท          -  ยท    1340833  ยท        4.5 %  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AOwnersExplicitMock                                    ยท          -  ยท          -  ยท    1255001  ยท        4.2 %  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AOwnersExplicitStartTokenIdMock                        ยท          -  ยท          -  ยท    1329560  ยท        4.4 %  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721AStartTokenIdMock                                      ยท          -  ยท          -  ยท    1405490  ยท        4.7 %  ยท          -  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ERC721ReceiverMock                                           ยท          -  ยท          -  ยท     207526  ยท        0.7 %  ยท          -  โ”‚
ยท---------------------------------------------------------------|-------------|-------------|-------------|---------------|-------------ยท

There aren't any gas reporter mocks for _burn functionality right now, but as you can see above with only test reports:

  1. ERC721ABurnableMock burn call, Avg. gas reduced 1,803, Max. gas used reduced 2,511
  2. ERC721ABurnableMock deployment, reduced 624.
  3. ERC721AMock deployment, the same as before.

By the _ownershipOf nature, if the batch size is high, this fix reduces runtime gas even more.
Also, if the child contract doesn't use approvalCheck at all, the compiler optimize the if block away.

I will open a PR with above fix, but without the wrapper for _burn. If the wrapper is good, tell me to add it and _burn wrapper.

Make setApprovalForAll virtual

Hello!

Would it be possible to make setApprovalForAll virtual? That's the case in OpenZeppelin's ERC721 implementation. Or are there any reasons why isApprovedForAll is virtual, but not setApprovalForAll?

It would be useful because of the various gas optimization strategies involving approving marketplace proxys by default (among others), which require you to override isApprovedForAll to add some custom logic.

IMHO, some custom logic is also necessary in setApprovalForAll so users can revoke those default approvals the same way they'd revoke any address's approvals, thus why I would like to be able to override that method.

Documentation for Aux / Aux Use Case

First of all, thank you @chiru-labs for your contribution to the open-source community with ERC721A. I really enjoyed reading the following article and picking through the contract code.

https://www.azuki.com/erc721a

I've noticed you've made some additions since I implemented ERC721A in my contract, but there is no documentation or official changelog for these changes other than just examining the commits.

I'm wondering why the inclusion of the burn function in the base ERC721A contract. Would it not have been more ideal to create a separate contract that implements burning functionality than including it in the base contract? None of the projects I've been involved with have desired this functionality and I'm wondering if the extra logic it requires increases gas costs at all.

I'm also wondering if the purpose of the aux field can be explained better. I see that the comments indicate it is used to indicate how many "whitelist slots" have been used.

In my team's contract we use an off-chain API we created for generating a Merkle root hash (that is then set on a contract) and for generating Merkle proofs which are submitted to our whitelistMint function. Once a whitelisted address calls the function, they are immediately invalidated by setting whitelistClaimed[_msgSender()] = true;. The problem with this is that if we allow whitelisted users to mint a total of let's say 3 tokens, but they only choose to mint 1, they are invalidated from the whitelist after their first call to the function and cannot mint any more.

uint256 private maxWhitelistMints = 3;
  // @notice this is the mint function, mint Fees in ERC20,
  //  requires amount * mintPrice to be sent by caller
  //  nonReentrant() function. More comments within code.
  // @param uint amount - number of tokens minted
  function whitelistMint(bytes32[] calldata merkleProof, uint256 amount) external payable nonReentrant() {
    // @notice using Checks-Effects-Interactions
    require(mintingActive, "Minting not enabled");
    require(whitelistActive, "Whitelist not required, use publicMint()");
    require(_msgValue() == mintPrice * amount, "Wrong amount of Native Token");
    require(_totalSupply() + amount <= mintSize, "Can not mint that many");
    require(amount <= maxWhitelistMints, "Exceeds maximum whitelist mints");
    require(
          MerkleProof.verify(
              merkleProof,
              whitelistMerkleRoot,
              keccak256(abi.encodePacked(_msgSender()))
          ),
          "Address not whitelisted"
    );
    require(!whitelistClaimed[_msgSender()], "You have already claimed your tokens");
    _safeMint(_msgSender(), amount);
    whitelistClaimed[_msgSender()] = true; 
  }

Personally, I'm fine with the way this works, since I think whitelisted addresses should only have one chance to mint the maximum number of tokens they are allowed to mint. However, ideally, we would keep track of how many they have minted respective to their maximum allowance, and allow them to call the function again if they have not yet exceeded this limit.

Is this the use case intention for the aux owner data with respect to whitelisting?

Question/Change Request: Init `currentIndex` with 1 instead of 0

We've been using ERC721A in our latest NFT drop. It worked great, however, having the token indexes start 0 caused some edgecases in our other contracts for the token with the id 0.

For example we have a simple staking contract were we map the owner address to their staked token. Each address can only stake a single token so its a mapping(address => uint256) ownerToToken. However, each address of the map get's initialized with 0 by solidity afaik. So doing stuff like require(ownerToToken[msg.sender] == 0, "Already staked a token"); does not work properly when supporting the token id 0 in the ERC721A contract.

Timestamp in Ownership

Why is the timestamp included in the ownership?
It seems more like an optional feature rather than a mandatory one to make the contract work.

If the point of ERC721A is to have an alternative version that saves on gas, then cutting it out seems to be the proper approach.

feat: migrate codebase from js to typescript

Typescript would offer a better development experience especially when it comes to smart contract types generated by hardhat which will allow faster and easier integration tests implementation.

I would do that if community is comfortable with typescript.

Unused errors

There are two unused errors in contracts/ERC721A.sol:

error OwnerIndexOutOfBounds();
error TokenIndexOutOfBounds();

One user can burn another user's tokens?

Hope I got it right - could always be my implementation.
I tried adding a burn functionality to my token. I added the following:

function burn(uint256 tokenId) public {
    _burn(tokenId);
    emit Burned(msg.sender, tokenId);
}

All it does is just pass the token id to _burn and emit an event.

I then added this test, which was supposed to fail:

it('should not allow user to burn an NFT they don\'t own', async () => {
      await myToken.connect(user1).mint(1, {value: ethers.utils.parseEther(regularPrice)});  //creates a single token with ID 0
      await myToken.connect(user2).burn(0);  //supposed to fail: user 1 owns token 0
});

But it does not. I looked into the _burn code, and it looks like it does not check ownership before proceeding to transfer the token to 0x0.

Should this check be enforced by my contract, or is there something missing in the _burn function?

seedAllowlist

Truffle through unit test try catch error this message appears to me does it affect the smart contract?

Invalid number of parameters for "allowlist". Got 0 expected 1!

function seedAllowlist(address[] memory addresses, uint256[] memory numSlots) external onlyOwner{ require( addresses.length == numSlots.length, "addresses does not match numSlots length"); for (uint256 i = 0; i < addresses.length; i++) { allowlist[addresses[i]] = numSlots[i]; } }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.