1

I am doing a two step minting process.

  1. user will setApprovalForAll for a new contract to transfer old tokens

  2. user will burn old tokens and mint new ones from the new contract

Burn and mint function below:

function BurnBabyBurn() 
    public
  {

    require(burnIsActive, "burn must be active to mint Final");
    require(BurnContract(piecesAddress).balanceOf(msg.sender, burnPieceIds[0]) > 0, "Must 
    have a balance for each piece");

    BurnContract(piecesAddress).safeTransferFrom(msg.sender, to, burnPieceIds[0], 
     burnPieceAmounts[0], "");

    _mint(msg.sender, finalPieceId, 1, "");
  }

When I run this on Mumbai everything works as expected. When I switch to matic mainnet I start to receive this error

"execution reverted: AssetContractShared#creatorOnly: ONLY_CREATOR_ALLOWED"

The tokens we are burning come from the opensea collectibles contract(0x2953399124F0cBB46d2CbACD8A89cF0599974963). Inside of that contract there is a modifier

/**
 * @dev Require msg.sender to be the creator of the token id
 */
modifier creatorOnly(uint256 _id) {
    require(
        _isCreatorOrProxy(_id, _msgSender()),
        "AssetContractShared#creatorOnly: ONLY_CREATORALLOWED"
    );
    ;
}

But this is where I am very confused as the modifier is only added to these functions: Mint, setURI, setPermanentURI, setCreator

Im not calling any of these functions. any idea why this could be happening?

Interface used above:

interface BurnContract {
   function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes calldata data
    ) external;
}
1
  • did you find a solution, got the same error
    – ProjectX
    Commented Dec 9, 2021 at 21:13

1 Answer 1

1

I was having the same problem with the Opensea contract, and, while I am not sure if this code is the one running the Opensea Storefront, the error message matches.

Let's have a look at the overriding safeTransformFrom function:

function safeTransferFrom(
    address _from,
    address _to,
    uint256 _id,
    uint256 _amount,
    bytes memory _data
) public override {
    uint256 mintedBalance = super.balanceOf(_from, _id);
    if (mintedBalance < _amount) {
        // Only mint what _from doesn't already have
        mint(_to, _id, _amount - mintedBalance, _data);
        if (mintedBalance > 0) {
            super.safeTransferFrom(_from, _to, _id, mintedBalance, _data);
        }
    } else {
        super.safeTransferFrom(_from, _to, _id, _amount, _data);
    }
}

Found here https://polygonscan.com/address/0x2953399124f0cbb46d2cbacd8a89cf0599974963#code (line 2141).

If you are calling the function as an address that has been approved, you actually don't own the token, so the balanceOf will return a value of 0, which will always be smaller than the _amount. So, the minting function is called. And that's where you have the modifier that leads to the error.

Unfortunately I don't know how to solve this. Passing a 0 _amount won't do the trick, because the balance of the token will remain unchanged.

UPDATE

I might have found a way:

  • test the balance of the token
  • if it has no balance, mint it first (from the transferring account)
  • then you can setApprovalForAll
  • then the transfer should work

Here is the transfer transaction: https://rinkeby.etherscan.io/tx/0x117cbf460dc1f340db4b63d61850fc82a075222cd7b0fc9a4c677665ac8d17d7

And here was the mint: https://rinkeby.etherscan.io/tx/0x95260c508d69f35d1b3566db44faacc1373d3d3e1bf6d74deb39f6e0c04e2f19

And here the setApprovalForAll: https://rinkeby.etherscan.io/tx/0xf750f7af34fb402d58eafc3c557cc3dec395ac18a57b7f1597c9deba37b2bafe

Please note that I haven't tested if minting into the target address would also work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.