I have created a smart contract in which I have a method called forSale used to store a flag (in a struct part of a mapping) indicating that the owner of an ERC721 token wishes to sell his said token (at a certain price). When a potential buyer wishes to buy the token, he calls a tokTransfer method in my smart contract, which verifies that the owner has indeed authorised the sell with the method above, before proceeding with the transaction. This is working perfectly. However, at no point in my smart contract, do I call either the approve or the setApprovalForAll method and my tokTransfer method calls only the _safeTransfer openzeppelin method, which never calls _isApprovedOrOwner, and the transaction is initiated by the purchaser in the owner's "absence". My question is, what if a smart contract does not implement a method similar to my forSale one, which sets a flag by the owner to sell the token at a determined price, does this mean that anyone could transfer the ownership of a token from the owner to himself at any price without the owner's knowledge? Isn't there a safety build within the blockchain itself to prevent a user from initiating the purchase of a token (NFT in this case) he doesn't own? Am I misunderstanding or missing something?
Struct and mapping:
struct TokensMinted {
bool minted;
bool forSale;
uint256 price;
}
mapping (uint256 => TokensMinted) private toksMinted;
Here is my forSale function, which sets the flag for selling:
function forSale(uint256 _tokenId, bool _val, uint256 _price) external {
require(msg.sender == ownerOf(_tokenId), 'Must be Owner of Token');
require(_price >= 0, 'Invalid Price');
toksMinted[_tokenId].forSale = _val;
toksMinted[_tokenId].price = _price;
emit ForSale(_tokenId, _val, _price);
}
And my tokTransfer method.
function tokTransfer(uint256 _tokenId) whenNotPaused() nonReentrant() external payable {
require(toksMinted[_tokenId].forSale == true, "This Token is not for Sale");
require(msg.value >= toksMinted[_tokenId].price, "Not enough MATICs");
address seller = ownerOf(_tokenId);
toksMinted[_tokenId].forSale = false;
uint256 commission = toksMinted[_tokenId].price.mul(commPerc).div(10000);
payable(seller).transfer(toksMinted[_tokenId].price.sub(commission));
_safeTransfer(seller, msg.sender, _tokenId, "");
}