Hi,
I have a question about staking and unstaking.
I have a ERC721 Contract where the user can mint and stake token in the same contract. So when the contract receives the token the onERC721Received function is called as it should. So everything is working fine so far. I write the original Owner and the tokenId into a mapping so I can retreive it later on.
Now comes the tricky part. When the user wants to unstake the token he or she staked earlier he/she is the caller of the safeTranferFrom function but not the owner. Rightfully the tx reverts. But how would I send the token from the contract back to the original Owner (retreived from my mapping). The owner of the token at that moment is the contract. So the caller is the user who is not the owner of the token so I would have to approve this transfer first. Where would I do that? How can I handle this? I thought about approving the transfer in the onERC721Received Function like so:
function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external virtual returns (bytes4)
{
require(msg.sender == address(this),"address must be contract");
approve(from, tokenId);
return _ERC721_RECEIVED;
}
Does this makes sense or is this a problem?
Any help would be appreciated.
UPDATE:
Here is the staking and unstaking function:
Staking:
function stake(uint256 tokenId) external payable {
require(msg.value >= stakingFee,"ether send is under staking price. ");
require(canStake,"You can't stake at the moment. Try again later.");
address gladiatorOwner = ownerOf(tokenId);
require(gladiatorOwner == msg.sender ||msg.sender == owner(),
"user ist not the owner of the token.");
mapAccountToCompetingTokens[gladiatorOwner].add(tokenId);
emit Staked(tokenId,gladiatorOwner);
// Sending the token from the owner to the contract
safeTransferFrom(gladiatorOwner,address(this), tokenId);
}
Unstaking:
function unstake(uint256 tokenId) external {
bool tokenBelongsToSender = false;
uint senderOwned = mapAccountToCompetingTokens[msg.sender].length();
for (uint i = 0; i<senderOwned;i++){
if(tokenId == mapAccountToCompetingTokens[msg.sender].at(i)){
tokenBelongsToSender = true;
break;
}
}
require(tokenBelongsToSender,"Token wasn't staked by you. Please choose another token");
transferFrom(address(this),msg.sender,tokenId);
}