Hi, I would like to add a marketplace to my DApp so my users can purchase their NFTs directly from us. I have successfully built the rariable clone a few times so I decided to expand on the tutorial to allow for the listing and purchasing 1155 NFTs. I have no issues adding items,or removing items for sale. But I cannot get the buyItem function to execute although the seller has been marked as a payable address I can also see the correct value is being sent. The error in remix is stating its not marked as payable. What am I missing any ideas?
smart contract
pragma solidity ^0.8.7;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.3.2/contracts/token/ERC1155/IERC1155.sol";
contract WalletMonstersMarketplace {
struct AuctionItem {
uint256 id;
address tokenAddress;
uint256 tokenId;
address payable seller;
uint256 askingPrice;
uint256 units;
bool isSold;
}
AuctionItem[] public itemsForSale;
mapping(address => mapping(uint256 => bool))activeItems; //know if item on sale
event itemAdded(uint256 id, uint256 tokenId, address tokenAddress,uint amount ,uint256 askingPrice);
event enjimonAdded(uint256 id, uint256 tokenId, address tokenAddress, uint256 askingPrice);
event itemSold(uint256 id, address buyer,uint256 amount, uint256 askingPrice);
event itemRemoved(uint256 id, address seller, uint256 amount, uint256 askingPrice, uint256 date);
modifier OnlyItemOwner(address tokenAddress, uint256 tokenId)
{
IERC1155 tokenContract = IERC1155(tokenAddress);
require(tokenContract.balanceOf(msg.sender, tokenId) > 0); //check if caller is owner of this token
_;
}
modifier HasTransferApproval(address tokenAddress, uint256 tokenId)
{
IERC1155 tokenContract = IERC1155(tokenAddress);
require(tokenContract.isApprovedForAll(msg.sender, address(this)) == true); //check if callers given contract approvals
_;
}
modifier ItemExist(uint256 id)
{
require(id < itemsForSale.length && itemsForSale[id].id == id,"could not find id");
_;
}
modifier IsForSale(uint256 id)
{
require(itemsForSale[id].isSold == false,"id already sold");
_;
}
function additemToMarket(uint256 tokenId, address tokenAddress,uint256 units, uint256 askingPrice) OnlyItemOwner(tokenAddress,tokenId) HasTransferApproval(tokenAddress,tokenId) external returns(uint256){
require(activeItems[tokenAddress][tokenId] == false,"Item up for sale already");
uint256 newItemId = itemsForSale.length;
itemsForSale.push(AuctionItem(newItemId, tokenAddress, tokenId, payable(msg.sender), askingPrice, units, false));
activeItems[tokenAddress][tokenId] = true; //items now up for sale
assert(itemsForSale[newItemId].id == newItemId);
emit itemAdded(newItemId, tokenId, tokenAddress, units ,askingPrice);
return newItemId;
}
function addEnjimonToMarket(uint256 tokenId, address tokenAddress, uint256 askingPrice) OnlyItemOwner(tokenAddress,tokenId) HasTransferApproval(tokenAddress,tokenId) external returns(uint256){
require(activeItems[tokenAddress][tokenId] == false,"Item up for sale already");
uint256 newItemId = itemsForSale.length;
itemsForSale.push(AuctionItem(newItemId, tokenAddress, tokenId,payable(msg.sender), askingPrice, 1, false));
activeItems[tokenAddress][tokenId] = true; //items now up for sale
assert(itemsForSale[newItemId].id == newItemId);
emit enjimonAdded(newItemId, tokenId, tokenAddress, askingPrice);
return newItemId;
}
function buyItem(uint256 id) payable external ItemExist(id) IsForSale(id) HasTransferApproval(itemsForSale[id].tokenAddress, itemsForSale[id].tokenId){
require(msg.value >= itemsForSale[id].askingPrice, "Not enough funds sent");
require(msg.sender != itemsForSale[id].seller);
address payable sellerAddress = payable(itemsForSale[id].seller);
itemsForSale[id].isSold = true; //items been marked as sold
activeItems[itemsForSale[id].tokenAddress][itemsForSale[id].tokenId] = false; //
IERC1155(sellerAddress).safeTransferFrom(sellerAddress, payable(msg.sender), itemsForSale[id].tokenId, itemsForSale[id].units, '');
sellerAddress.transfer(msg.value); //send funds to seller
emit itemSold(id, msg.sender, itemsForSale[id].units ,itemsForSale[id].askingPrice);
}
function removeItem(uint256 id) public ItemExist(id) IsForSale(id) returns(bool success){
require(msg.sender == itemsForSale[id].seller);
activeItems[itemsForSale[id].tokenAddress][itemsForSale[id].tokenId] = false;
delete itemsForSale[id];
emit itemRemoved(id, msg.sender, itemsForSale[id].units , itemsForSale[id].askingPrice, block.timestamp);
}
}