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 require(88 IERC721(_idCollection).ownerOf(_idNFT) == msg.sender,89 "Not right token owner"90 );91 uint256 offerID = asks[_idCollection][_idNFT];92 if (offers.length == 0 || offers[offerID].idCollection == address(0)) {93 offers.push(94 Offer(95 _idNFT,96 _currencyCode,97 _price,98 block.timestamp,99 _idCollection,100 msg.sender,101 _active102 )103 );104 asks[_idCollection][_idNFT] = offers.length - 1;105 asksbySeller[msg.sender].push(offers.length - 1);106 }107 //edit existing offer108 else {109 offers[asks[_idCollection][_idNFT]] = Offer(110 offers[asks[_idCollection][_idNFT]].idNFT,111 _currencyCode,112 _price,113 block.timestamp,114 offers[asks[_idCollection][_idNFT]].idCollection,115 msg.sender,116 _active117 );118 }119120 IERC721(_idCollection).transferFrom(msg.sender, address(this), _idNFT);121 }122123 function buy(address _idCollection, uint256 _idNFT) public payable {124 //buing for UNQ like as ethers125 Offer memory offer = offers[asks[_idCollection][_idNFT]];126 //1. check sent amount and send to seller127 require(128 msg.value == offer.price,129 "Not right amount UNQ sent, have to be equal price"130 );131 payable(offer.userAddr).transfer(offer.price);132 // 2. close offer133 offers[asks[_idCollection][_idNFT]].flagActive = 0;134 // 3. transfer NFT to buyer135 IERC721(_idCollection).transferFrom(address(this), msg.sender, _idNFT);136 }137138 function buy(139 address _idCollection,140 uint256 _idNFT,141 address _currencyCode,142 uint256 _amount143 ) public payable {144 Offer memory offer = offers[asks[_idCollection][_idNFT]];145 //1. check sent amount and transfer from buyer to seller146 require(147 offer.price == _amount && offer.currencyCode == _currencyCode,148 "Not right amount or currency sent, have to be equal currency and price"149 );150 // !!! transfer have to be approved to marketplace!151 IERC20(offer.currencyCode).transferFrom(152 msg.sender,153 address(this),154 offer.price155 );156 //to not disclojure buyer's address157 IERC20(offer.currencyCode).transfer(offer.userAddr, offer.price);158 // 2. close offer159 offers[asks[_idCollection][_idNFT]].flagActive = 0;160 // 3. transfer NFT to buyer161 IERC721(_idCollection).transferFrom(address(this), msg.sender, _idNFT);162 }163}