# How to prevent duplicate ERC1155 token IDs

**URL:** <https://forum.openzeppelin.com/t/how-to-prevent-duplicate-erc1155-token-ids/25052>\
**Category:** Smart Contracts\
**Tags:** erc1155\
**Created:** [February 21, 2022, 6:01am UTC](https://forum.openzeppelin.com/t/how-to-prevent-duplicate-erc1155-token-ids/25052 "2022-02-21T06:01:22Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![mow](https://avatars.discourse-cdn.com/v4/letter/m/7ab992/32.png) [@mow](https://forum.openzeppelin.com/u/mow)\
**Post date:** [February 21, 2022, 6:01am UTC](https://forum.openzeppelin.com/t/how-to-prevent-duplicate-erc1155-token-ids/25052/1 "2022-02-21T06:01:23Z")

</div>

I found that I could mint a new token with the same token ID as a previously minted token under the same ERC1155 contract.

There was no error about duplicate ID. This would defeat the notion of uniqueness / scarcity / non-fungibility of NFTs.

Are we meant to add custom code ourselves into our ERC1155 contract in order to prevent this?

---

<div class="post-metadata">

**Author:** ![mow](https://avatars.discourse-cdn.com/v4/letter/m/7ab992/32.png) [@mow](https://forum.openzeppelin.com/u/mow)\
**Post date:** [February 21, 2022, 7:08am UTC](https://forum.openzeppelin.com/t/how-to-prevent-duplicate-erc1155-token-ids/25052/2 "2022-02-21T07:08:21Z")

</div>

I notice that OpenZeppelin provides `ERC1155Supply` that we could use to check for duplicates. But isn't it weird that duplication checks aren't included in the ERC1155 standard?

So would adding this `require` fix it for single token miniting?

```auto
    function mint(
        address account,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) public onlyOwner {
        require(!ERC1155Supply.exists(id), "Token with that id has already been minted");

        _mint(account, id, amount, data);
    }

```

I've also done a test with `mintBatch` by adding a duplicate token ID in the `ids` array and found that 11 tokens got minted for that token ID, even though only `1` was passed in `amounts` for each token to be minted. Please fix this bug.

In the meantime, what's the most efficient way to deduplicate the arrays that are passed into `mintBatch`?

---

<div class="post-metadata">

**Author:** ![mow](https://avatars.discourse-cdn.com/v4/letter/m/7ab992/32.png) [@mow](https://forum.openzeppelin.com/u/mow)\
**Post date:** [February 21, 2022, 7:15am UTC](https://forum.openzeppelin.com/t/how-to-prevent-duplicate-erc1155-token-ids/25052/3 "2022-02-21T07:15:33Z")

</div>

> [@mow](#):
>
> found that 11 tokens got minted for that token ID

Is this caused by string concatenation instead of mathematical addition in  
[https://github.com/OpenZeppelin/openzeppelin-contracts/blob/a5445b0afb8b350417b6e6ab3160554967bc151f/contracts/token/ERC1155/ERC1155.sol#L301](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/a5445b0afb8b350417b6e6ab3160554967bc151f/contracts/token/ERC1155/ERC1155.sol#L301) ?

I had passed the array of integers `[1, 1, 1]` for `amounts` from a hardhat scrript.

---

<div class="post-metadata">

**Author:** ![mow](https://avatars.discourse-cdn.com/v4/letter/m/7ab992/32.png) [@mow](https://forum.openzeppelin.com/u/mow)\
**Post date:** [February 21, 2022, 8:48am UTC](https://forum.openzeppelin.com/t/how-to-prevent-duplicate-erc1155-token-ids/25052/4 "2022-02-21T08:48:02Z")

</div>

That code works for single token minting, I've just tested.

For batch minting this code works:

```auto

function mintBatch(
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data

    ) public onlyOwner {
        for (uint256 i = 0; i < ids.length - 1; i++) {
            require(
                !ERC1155Supply.exists(ids[i]),
                "ids contains tokens that have already been minted"
            );
        }

        require(!hasDuplicate(ids), "ids has duplicates");

        _mintBatch(to, ids, amounts, data);
    }

```

`hasDuplicate` is in:

> <https://github.com/cryptofinlabs/cryptofin-solidity/blob/dafccd0a0aa184be4270db226bc5ef99d7376a24/contracts/array-utils/AddressArrayUtils.sol#L299>

Are these the most elegant workarounds?

---

<div class="post-metadata">

**Author:** ![mow](https://avatars.discourse-cdn.com/v4/letter/m/7ab992/32.png) [@mow](https://forum.openzeppelin.com/u/mow)\
**Post date:** [March 9, 2022, 6:21pm UTC](https://forum.openzeppelin.com/t/how-to-prevent-duplicate-erc1155-token-ids/25052/6 "2022-03-09T18:21:52Z")

</div>

This is more is efficient, but are 2 loops really needed?:

```auto
function mintBatch(
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) public onlyOwner {
        for (uint256 i = 0; i < ids.length - 1; i++) {
            require(!ERC1155Supply.exists(ids[i]), "ids array contains IDs of tokens that have already been minted");

            for (uint256 j = i + 1; j < ids.length; j++)
                require(ids[i] != ids[j], "ids has duplicates");
        }
        require(!ERC1155Supply.exists(ids[ids.length - 1]), "ids array contains IDs of tokens that have already been minted");

        _mintBatch(to, ids, amounts, data);
    }

```
