Transfer an ERC721 from a contract to a wallet

Good morning.
In order to create a sort of renting service I need to a mirrored version of an ERC721 contract.
The mirrored version is the token that will be transferred to the borrower wallet after the accepting the loaning agreement.
Since is fundamental to have the mirrored ERC721 into the original smart contract (mirrored version) I was wondering is it is possible to mint the tokens into the contract itself and then transfer them at a later stage.

Step by step target example:

1.Deploy MirroredContract
2. Mint full tokens supply into the MirroredContract
3. Transfer a token from the MirroredContract to an external wallet

My question is: is possible to do the operation at the point 3 with an ERC721 contract?

Thank for the help in advance.

Not sure what you mean with mirrored contract. However your contract can mint an erc721 for itself and your contract can transfer erc721’s to another contract if you implement that functionality. So to answer the question, yes that is possible.

Or to an external wallet, which is what this user asks about.

Doesn’t really matter, functionally for this situation there is no difference between a contract and a wallet. You can see a wallet just as a smart contract without any logic :slight_smile:

I can, but the dude who asked this question might not be (able to understand this)

Thank you for the response!
I try to clarify the question.
I have the logic contract for handling the loaning and the ERC721 that represents the avatars to loan.
I need to call from within the loaning contract a function that transfer a token that is currently into the ERC721 to another wallet.

Is it possible?

Yes, as already explained in the original answer to your question

I was asking since I got an error.
Could be the problem that I need the contract ERC721 to approve the logic contract in order to transfer the tokens?

It could, but you'll obviously need to share some more details.

Specifically, your code, as well as the error that you've encountered.

Unfortunately I can't because of NDA stuff. Thank you for your availability, I'll try in a different way!

The relevant code should be about 3 lines (and the error - probably just 1 line).
There shouldn't be any proprietary non-generic information to disclose here, but suit yourself...

Ok I try with the related lines:

I call this function after creating the instance of the borrowing contract into the logic one.

loanedAvatarInstance.transferAvatarToTheBorrower(msg.sender, loanDetails.avatarId);

From within the ERC721 contract I call the function below:

function transferAvatarToTheBorrower(address borrower, uint256 tokenId) public onlyRole(LOANER_ROLE) {
        super.transferFrom(address(this), borrower, tokenId);
    }

Yes, transferFrom(address(this), borrower, tokenId) requires a preliminary approval.

But you could just use transfer(borrower, tokenId) instead, because your contract (this) needs to transfer from itself, not from some another account.

Having said that, I am describing an ERC20-scenario here, so you'll need to check whether or not this solution is applicable for ERC721 as well.

Yes that’s possible, you just need to make sure the logic contract is approved to do the transfer.

I don't think that you can act as a smart contract to approve another...
At least I've never heard about something like this.
In this case I would need the ERC721 itself to approve the logic contract, but since the approval (and setApprovalForAll) function get the approver as the msg.sender I don't see it feasible at all.

In my experiences I've worked with ERC20 in this way and I confirm that this is possible.
On the other hand, talking about ERC721 I don't think that this is possible at all starting from the ERC721 implementation of Openzeppelin. Is something that needs a deep change, but is better to don't do it I think.

The original owner sends something to the logic contract. The logic contract mints a token, the logic contract sends the minted token to another address. As the logic contract is the owner of the minted token it is allowed to approve its own stuff if needed.

Even if the minted token is not created by the logic contract, whoever/whatever mints the token can also call the approve for the logic contract for that token.

I’m confused as tovert you think that’s not possible? Also this logic is used a lot in contracts with borrowlending platforms that use NFT’s

I've figured out a possible solution that involves to mint all the tokens to an external owned wallet that acts as a temporary pool with limitations in transferring the tokens.
Having full access to this wallet I can approve the logic contract to send the tokens reaching a nice tradeoff.

One of my requirements is that the owner of the original avatar cannot own at the same time the avatar and the mirrored version.
Moreover, I've a question. Who can call the setApproveForAll function? The owner of the token or the minter?

The owner of the token is the one that needs to approve the transfers

This for me is probably wrong, or at least I don't know how to call the approval acting as the logic contract.
Do you have any suggestions?
Thank you for your help by the way!