The protocol transfers NFTs from owners to itself and from itself to other users. ERC721 defines safe functions that check whether a smart contract can safely handle NFTs in order to prevent permant locks. However, the current market place uses the unsafe transferFrom function.
EOA present no issue, but contracts as receivers are common.
Transferring an NFT into a contract that does not implement ERC-721 receiving semantics can leave the token irretrievable.
function test_unsafe_transfer() public {
RejectNFTReceiver rejectNFTReceiver = new RejectNFTReceiver();
vm.deal(address(rejectNFTReceiver), STARTING_BALANCE);
vm.prank(PROTOCOL_OWNER);
nft.mint(SELLER);
uint256 askPrice = MIN_PRICE + 1;
uint256 buyNowPrice = askPrice + 1;
vm.startPrank(SELLER);
nft.approve(address(market), 0);
vm.expectEmit(true, true, true, true);
emit NftListed(0, SELLER, askPrice, buyNowPrice);
market.listNFT(0, askPrice, buyNowPrice);
vm.stopPrank();
assertEq(nft.ownerOf(0), address(market));
BidBeastsNFTMarket.Listing memory listing = market.getListing(0);
assertEq(listing.listed, true);
assertEq(listing.seller, SELLER);
assertEq(listing.minPrice, askPrice);
assertEq(listing.buyNowPrice, buyNowPrice);
assertEq(listing.auctionEnd, 0);
vm.warp(1 days);
uint256 sellerStartingBalance = SELLER.balance;
uint256 protocolFeeStartingBalance = market.s_totalFee();
vm.startPrank(address(rejectNFTReceiver));
vm.expectEmit(true, true, true, true);
emit AuctionSettled(0, address(rejectNFTReceiver), SELLER, buyNowPrice);
market.placeBid{value: buyNowPrice}(0);
vm.stopPrank();
uint256 sellerEndingBalance = SELLER.balance;
uint256 protocolFeeEndingBalance = market.s_totalFee();
listing = market.getListing(0);
assertEq(listing.listed, false);
assertEq(listing.seller, SELLER);
assertEq(listing.minPrice, askPrice);
assertEq(listing.buyNowPrice, buyNowPrice);
assertEq(listing.auctionEnd, 0);
BidBeastsNFTMarket.Bid memory bid = market.getHighestBid(0);
assertEq(bid.bidder, address(0));
assertEq(bid.amount, 0);
assertEq(nft.ownerOf(0), address(rejectNFTReceiver));
}