1// SPDX-License-Identifier: Apache License2pragma solidity >=0.8.0;34interface IERC721 {5 event Transfer(6 address indexed from,7 address indexed to,8 uint256 indexed tokenId9 );10 event Approval(11 address indexed owner,12 address indexed approved,13 uint256 indexed tokenId14 );1516 function ownerOf(uint256 tokenId) external view returns (address owner);1718 function transferFrom(19 address from,20 address to,21 uint256 tokenId22 ) external;2324 function debug(string memory value) external;25}2627interface IERC20 {28 event Transfer(address indexed from, address indexed to, uint256 value);29 event Approval(30 address indexed owner,31 address indexed spender,32 uint256 value33 );3435 function transfer(address recipient, uint256 amount)36 external37 returns (bool);3839 function transferFrom(40 address sender,41 address recipient,42 uint256 amount43 ) external returns (bool);44}4546contract MarketPlaceUNQ {47 struct Offer {48 uint256 idNFT;49 address currencyCode; //address of currency token, = address(0) for UNQ50 uint256 price;51 uint256 time;52 address idCollection;53 address userAddr;54 uint8 flagActive;55 }56 Offer[] public offers;5758 mapping(address => mapping(uint256 => uint256)) public asks; // [idCollection][idNFT] => idOffer5960 mapping(address => uint256[]) public asksbySeller; // [addressSeller] =>idOffer6162 address owner;6364 constructor() {65 owner = msg.sender;66 }6768 function setowner(address _newOwner) public onlyOwner {69 owner = _newOwner;70 }7172 modifier onlyOwner() {73 require(msg.sender == owner, "Only owner can");74 _;75 }7677 /**78 * Make bids (offers) to sell NFTs79 */80 function setAsk(81 uint256 _price,82 address _currencyCode,83 address _idCollection,84 uint256 _idNFT,85 uint8 _active86 ) public {87 IERC721(_idCollection).debug("ask");88 require(89 IERC721(_idCollection).ownerOf(_idNFT) == msg.sender,90 "Not right token owner"91 );92 uint256 offerID = asks[_idCollection][_idNFT];93 if (offers.length == 0 || offers[offerID].idCollection == address(0)) {94 offers.push(95 Offer(96 _idNFT,97 _currencyCode,98 _price,99 block.timestamp,100 _idCollection,101 msg.sender,102 _active103 )104 );105 asks[_idCollection][_idNFT] = offers.length - 1;106 asksbySeller[msg.sender].push(offers.length - 1);107 }108 //edit existing offer109 else {110 offers[asks[_idCollection][_idNFT]] = Offer(111 offers[asks[_idCollection][_idNFT]].idNFT,112 _currencyCode,113 _price,114 block.timestamp,115 offers[asks[_idCollection][_idNFT]].idCollection,116 msg.sender,117 _active118 );119 }120121 IERC721(_idCollection).transferFrom(msg.sender, address(this), _idNFT);122 }123124 function buy(address _idCollection, uint256 _idNFT) public payable {125 //buing for UNQ like as ethers126 Offer memory offer = offers[asks[_idCollection][_idNFT]];127 //1. check sent amount and send to seller128 require(129 msg.value == offer.price,130 "Not right amount UNQ sent, have to be equal price"131 );132 payable(offer.userAddr).transfer(offer.price);133 // 2. close offer134 offers[asks[_idCollection][_idNFT]].flagActive = 0;135 // 3. transfer NFT to buyer136 IERC721(_idCollection).transferFrom(address(this), msg.sender, _idNFT);137 }138139 function buy(140 address _idCollection,141 uint256 _idNFT,142 address _currencyCode,143 uint256 _amount144 ) public payable {145 Offer memory offer = offers[asks[_idCollection][_idNFT]];146 //1. check sent amount and transfer from buyer to seller147 require(148 offer.price == _amount && offer.currencyCode == _currencyCode,149 "Not right amount or currency sent, have to be equal currency and price"150 );151 // !!! transfer have to be approved to marketplace!152 IERC20(offer.currencyCode).transferFrom(153 msg.sender,154 address(this),155 offer.price156 );157 //to not disclojure buyer's address158 IERC20(offer.currencyCode).transfer(offer.userAddr, offer.price);159 // 2. close offer160 offers[asks[_idCollection][_idNFT]].flagActive = 0;161 // 3. transfer NFT to buyer162 IERC721(_idCollection).transferFrom(address(this), msg.sender, _idNFT);163 }164}