git.delta.rocks / unique-network / refs/commits / a478235c0b6e

difftreelog

source

js-packages/tests/eth/marketplace/MarketPlace.sol14.6 KiBsourcehistory
1// SPDX-License-Identifier:  Apache License2pragma solidity >=0.8.0;3import {UniqueNFT, Dummy, ERC165} from "../api/UniqueNFT.sol";45// Inline6interface ERC20Events {7    event Transfer(address indexed from, address indexed to, uint256 value);8    event Approval(9        address indexed owner,10        address indexed spender,11        uint256 value12    );13}1415interface ERC20 is Dummy, ERC165, ERC20Events {16    // Selector: name() 06fdde0317    function name() external view returns (string memory);1819    // Selector: symbol() 95d89b4120    function symbol() external view returns (string memory);2122    // Selector: totalSupply() 18160ddd23    function totalSupply() external view returns (uint256);2425    // Selector: decimals() 313ce56726    function decimals() external view returns (uint8);2728    // Selector: balanceOf(address) 70a0823129    function balanceOf(address owner) external view returns (uint256);3031    // Selector: transfer(address,uint256) a9059cbb32    function transfer(address to, uint256 amount) external returns (bool);3334    // Selector: transferFrom(address,address,uint256) 23b872dd35    function transferFrom(36        address from,37        address to,38        uint256 amount39    ) external returns (bool);4041    // Selector: approve(address,uint256) 095ea7b342    function approve(address spender, uint256 amount) external returns (bool);4344    // Selector: allowance(address,address) dd62ed3e45    function allowance(address owner, address spender)46        external47        view48        returns (uint256);49}5051interface UniqueFungible is Dummy, ERC165, ERC20 {}5253contract MarketPlace {54    struct Order {55        56        uint256 idNFT;57        address currencyCode; // UNIQ tokens as address address (1); wKSM 58        uint256 price;59        uint256 time;60        address idCollection;61        address ownerAddr;62        uint8 flagActive;63        string name;64        string symbol;65        string tokenURI;        66    }67    Order[] public  orders;68    uint test;69    mapping (address => uint256) public balanceKSM;  //  [ownerAddr][currency] => [KSMs]70    mapping (address => mapping (uint256 => uint256)) public  asks ; // [buyer][idCollection][idNFT] => idorder71    mapping (address => mapping (uint => uint[])) public ordersbyNFT; // [addressCollection] =>idNFT =>idorder7273    mapping (address => uint[]) public asksbySeller; // [addressSeller] =>idorder7475    mapping (address =>bool) internal isEscrow;7677    //address escrow;78    address owner;79    address nativecoin;8081    // from abstract contract ReentrancyGuard 82    // Booleans are more expensive than uint256 or any type that takes up a full83    // word because each write operation emits an extra SLOAD to first read the84    // slot's contents, replace the bits taken up by the boolean, and then write85    // back. This is the compiler's defense against contract upgrades and86    // pointer aliasing, and it cannot be disabled.8788    // The values being non-zero value makes deployment a bit more expensive,89    // but in exchange the refund on every call to nonReentrant will be lower in90    // amount. Since refunds are capped to a percentage of the total91    // transaction's gas, it is best to keep them low in cases like this one, to92    // increase the likelihood of the full refund coming into effect.93    uint8 private constant _NOT_ENTERED = 1;94    uint8 private constant _ENTERED = 2;9596    uint8 private _status;9798    struct NFT {99        address  collection;100        uint256 id;101    }102    103     //function initialize() public initializer {104   constructor () { // call setEscrow directly105        owner = msg.sender;106107         orders.push(Order(        108                    0,109                    address(0),110                    0,111                    0,112                    address(0),113                    address(0),114                    0, "","",""));115         _status = _NOT_ENTERED;116117    }118119    modifier nonReentrant() { // from abstract contract ReentrancyGuard 120        // On the first call to nonReentrant, _notEntered will be true121        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");122123        // Any calls to nonReentrant after this point will fail124        _status = _ENTERED;125126        _;127128        // By storing the original value once again, a refund is triggered (see129        // https://eips.ethereum.org/EIPS/eip-2200)130        _status = _NOT_ENTERED;131    }132133    modifier onlyEscrow () {134        require(isEscrow [msg.sender] , "Only escrow can");135        _;136    }137138    modifier onlyOwner () {139        require(msg.sender == owner, "Only owner can");140        _;141    }142143    /**144    * Make bids (orders) to sell NFTs 145    */146147     148    receive  () external payable  {149     //   revert ("Can't accept payment without collection and IDs, use dApp to send");150    }151    fallback () external payable {152        revert ("No such function");153    } 154155    event AddedAsk (uint256 _price, 156                    address  _currencyCode, 157                    address _idCollection, 158                    uint256 _idNFT,159                    uint256 orderId160                  );161    event EditedAsk (uint256 _price, 162                    address  _currencyCode, 163                    address _idCollection, 164                    uint256 _idNFT,165                    uint8  _active,166                    uint orderId);167168    event  CanceledAsk (address _idCollection, 169                        uint256 _idNFT, 170                        uint orderId171                        );172173    event DepositedKSM (uint256 _amount,  address _sender);174175    event BoughtNFT4KSM (address _idCollection, uint256 _idNFT, uint orderID, uint orderPrice );176177    event BoughtNFT (address _idCollection, uint256 _idNFT, uint orderID, uint orderPrice );178179    event WithdrawnAllKSM (address _sender, uint256 balance); 180181    event WithdrawnKSM (address _sender, uint256 balance); 182183    event Withdrawn (uint256 _amount, address _currencyCode, address _sender);184    185186   function setOwner  (address _newOwner) public onlyOwner {187        owner = _newOwner;188    }189190    function setEscrow  (address _escrow, bool _state) public onlyOwner returns (bool) {191        if (isEscrow[_escrow] != _state)  {192            isEscrow[_escrow] = _state;193            return true;194        }195        return false;196    }197198    function setNativeCoin  (address _coin) public onlyOwner {199        nativecoin = _coin;200    }201202203    function addAsk (uint256 _price, 204                    address  _currencyCode, 205                    address _idCollection, 206                    uint256 _idNFT207                  ) public  { //208        address ownerNFT = UniqueNFT(_idCollection).ownerOf(_idNFT);209        require (ownerNFT == msg.sender, "Only token owner can make ask");210        string memory nameNFT;211        string memory symbolNFT;212        string memory uriNFT;213        try UniqueNFT(_idCollection).name() returns (string memory name_) {214            nameNFT = name_;215        }216        catch {217            nameNFT="";218        }   219        try UniqueNFT(_idCollection).symbol() returns (string memory symbol_) {220            symbolNFT = symbol_;221        }222        catch {223            symbolNFT="";224        }  225        try UniqueNFT(_idCollection).tokenURI(_idNFT) returns (string memory uri_) {226            uriNFT = uri_;227        }228        catch {229            uriNFT="";230        }        231        orders.push(Order(        232                    _idNFT,233                    _currencyCode,234                    _price,235                    block.timestamp,236                    _idCollection,237                    msg.sender,238                    1, // 1 = is active239                    nameNFT, 240                    symbolNFT,241                    uriNFT242             ));243            244            uint orderId = orders.length-1;245            asks[_idCollection][_idNFT] = orderId;246            asksbySeller[msg.sender].push(orderId);247            UniqueNFT(_idCollection).transferFrom(msg.sender, address(this), _idNFT);248            emit AddedAsk(_price, _currencyCode, _idCollection, _idNFT, orderId);     249    }250251    function editAsk (uint256 _price, 252                    address  _currencyCode, 253                    address _idCollection, 254                    uint256 _idNFT,255                    uint8  _active) public {256        257258        uint orderID =  asks[_idCollection][_idNFT];259260        require (orders[orderID].ownerAddr == msg.sender, "Only token owner can edit ask");261        require (orders[orderID].flagActive != 0, "This ask is closed");262        if (_price> 0 ) {263            orders[orderID].price = _price ;  264        }265        266        if (_currencyCode != address(0) ) {267            orders[orderID].currencyCode = _currencyCode ;  268        }269270        orders[orderID].time = block.timestamp;271        orders[orderID].flagActive = _active;272        273        emit EditedAsk(_price, _currencyCode, _idCollection, _idNFT, _active, orderID);274        }275        276277    function cancelAsk (address _idCollection, 278                        uint256 _idNFT279                        ) public {280281        uint orderID =  asks[_idCollection][_idNFT];282283        require (orders[orderID].ownerAddr == msg.sender, "Only token owner can edit ask");284        require (orders[orderID].flagActive != 0, "This ask is closed");285286        orders[orderID].time = block.timestamp;287        orders[orderID].flagActive = 0;288        UniqueNFT(_idCollection).transferFrom(address(this),orders[orderID].ownerAddr, _idNFT);289        emit CanceledAsk(_idCollection, _idNFT, orderID);290        }291292293    function depositKSM (uint256 _amount,  address _sender) public onlyEscrow {294        balanceKSM[_sender] = balanceKSM[_sender] + _amount;295        emit DepositedKSM(_amount, _sender);296    }297298    function buyKSM (address _idCollection, uint256 _idNFT, address _buyer, address _receiver ) public {299        300        Order memory order = orders[ asks[_idCollection][_idNFT]];301        require(isEscrow[msg.sender]  || msg.sender == _buyer, "Only escrow or buyer can call buyKSM" );302        //1. reduce balance303304        balanceKSM[_buyer] = balanceKSM[_buyer] - order.price;305        balanceKSM[order.ownerAddr] = balanceKSM[order.ownerAddr] + order.price;306        // 2. close order307        orders[ asks[_idCollection][_idNFT]].flagActive = 0;308        // 3. transfer NFT to buyer309        UniqueNFT(_idCollection).transferFrom(address(this), _receiver, _idNFT);310        emit BoughtNFT4KSM(_idCollection, _idNFT, asks[_idCollection][_idNFT], order.price);311312    }313    function buy (address _idCollection, uint256 _idNFT ) public payable returns (bool result) { //buing for UNQ like as ethers 314        315        Order memory order = orders[asks[_idCollection][_idNFT]]; 316        //1. check sent amount and send to seller317        require (msg.value == order.price, "Not right amount sent, have to be equal price" );     318        // 2. close order319        orders[ asks[_idCollection][_idNFT]].flagActive = 0;320        321        // 3. transfer NFT to buyer322        UniqueNFT(_idCollection).transferFrom(address(this), msg.sender, _idNFT);323        //uint balance  = address(this).balance;324        result = payable(order.ownerAddr).send (order.price); 325        emit BoughtNFT(_idCollection, _idNFT, asks[_idCollection][_idNFT], order.price);326        327    }328329/* 330    function buyOther (address _idCollection, uint256 _idNFT, address _currencyCode, uint _amount ) public  { //buy for sny token if seller wants331        332        Order memory order = orders[ asks[_idCollection][_idNFT]];333        //1. check sent amount and transfer from buyer to seller334        require (order.price == _amount && order.currencyCode == _currencyCode, "Not right amount or currency sent, have to be equal currency and price" );335        // !!! transfer have to be approved to marketplace!336        UniqueFungible(order.currencyCode).transferFrom(msg.sender, address(this), order.price); //to not disclojure buyer's address 337        UniqueFungible(order.currencyCode).transfer(order.ownerAddr, order.price);338        // 2. close order339        orders[ asks[_idCollection][_idNFT]].flagActive = 0;340        // 3. transfer NFT to buyer341        UniqueNFT(_idCollection).transferFrom(address(this), msg.sender, _idNFT);342343344    }345 */346347    function withdrawAllKSM (address _sender) public  nonReentrant returns (uint lastBalance ){348        require(isEscrow[msg.sender]  || msg.sender == _sender, "Only escrow or balance owner can withdraw all KSM" );349350        lastBalance = balanceKSM[_sender];351        balanceKSM[_sender] =0;352        emit WithdrawnAllKSM(_sender, lastBalance);353    }354355    function withdrawKSM (uint _amount, address _sender) onlyEscrow public {356        balanceKSM[_sender] = balanceKSM[_sender] - _amount;357        emit WithdrawnKSM(_sender, balanceKSM[_sender]);358        359    }360361    function withdraw (uint256 _amount, address _currencyCode) public  nonReentrant returns (bool result ){ //onlyOwner362        address payable _sender = payable( msg.sender);363        if (_currencyCode != nativecoin ) { //erc20 compat. tokens on UNIQUE chain364            // uint balance = UniqueFungible(_currencyCode).balanceOf(address(this));365            UniqueFungible(_currencyCode).transfer(_sender, _amount);366        } else {367            // uint balance  = address(this).balance;368369            result =  (_sender).send(_amount); // for UNQ like as ethers 370        }371        emit Withdrawn(_amount, _currencyCode, _sender);372        return result;373374    }375376    377   // event GettedOrder(uint , Order);378    function getOrder (address _idCollection, uint256 _idNFT) public view returns (Order memory) {379        uint orderId = asks[_idCollection][_idNFT];380        Order memory order = orders[orderId];381 //       emit GettedOrder (orderId, order);382        return order;383    }384385    function getOrdersLen () public view returns (uint) {386        return orders.length;387    }388389    function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) public pure returns(bytes4) {390            return bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"));391        }392     393    //TODO make destructing function to return all 394    function terminate(address[] calldata tokens, NFT[] calldata nfts) public onlyOwner {395    // Transfer tokens to owner (TODO: error handling)396        for (uint i = 0; i < tokens.length; i++) {397            address addr = tokens[i];398            UniqueFungible token = UniqueFungible(addr);399            uint256 balance = token.balanceOf(address(this));400            token.transfer(owner, balance);401        }402        for (uint i = 0; i < nfts.length; i++) {403            address addr = nfts[i].collection;404            UniqueNFT token = UniqueNFT(addr);405            token.transferFrom(address(this), owner, nfts[i].id);406        }    407    // Transfer Eth to owner and terminate contract408        address payable owner1 = payable (owner);409        uint balance = address(this).balance;410        owner1.transfer(balance);411        412    } 413    414}