git.delta.rocks / unique-network / refs/commits / 7a0df1a2d7c5

difftreelog

MarketPlace.sol from unique-marketplace

Andrey2022-11-10parent: #7bd00bb.patch.diff
in: master

5 files changed

deletedtests/src/eth/marketplace/MarketPlace.abidiffbeforeafterboth
--- a/tests/src/eth/marketplace/MarketPlace.abi
+++ /dev/null
@@ -1 +0,0 @@
-[{"inputs":[{"internalType":"address","name":"_escrow","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_price","type":"uint256"},{"indexed":false,"internalType":"address","name":"_currencyCode","type":"address"},{"indexed":false,"internalType":"address","name":"_idCollection","type":"address"},{"indexed":false,"internalType":"uint256","name":"_idNFT","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"orderId","type":"uint256"}],"name":"AddedAsk","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_idCollection","type":"address"},{"indexed":false,"internalType":"uint256","name":"_idNFT","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"orderID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"orderPrice","type":"uint256"}],"name":"BoughtNFT","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_idCollection","type":"address"},{"indexed":false,"internalType":"uint256","name":"_idNFT","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"orderID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"orderPrice","type":"uint256"}],"name":"BoughtNFT4KSM","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_idCollection","type":"address"},{"indexed":false,"internalType":"uint256","name":"_idNFT","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"orderId","type":"uint256"}],"name":"CanceledAsk","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"_sender","type":"address"}],"name":"DepositedKSM","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_price","type":"uint256"},{"indexed":false,"internalType":"address","name":"_currencyCode","type":"address"},{"indexed":false,"internalType":"address","name":"_idCollection","type":"address"},{"indexed":false,"internalType":"uint256","name":"_idNFT","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"_active","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"orderId","type":"uint256"}],"name":"EditedAsk","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"_currencyCode","type":"address"},{"indexed":false,"internalType":"address","name":"_sender","type":"address"}],"name":"Withdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"balance","type":"uint256"}],"name":"WithdrawnAllKSM","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"address","name":"_currencyCode","type":"address"},{"internalType":"address","name":"_idCollection","type":"address"},{"internalType":"uint256","name":"_idNFT","type":"uint256"}],"name":"addAsk","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"asks","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"asksbySeller","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceKSM","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_idCollection","type":"address"},{"internalType":"uint256","name":"_idNFT","type":"uint256"}],"name":"buy","outputs":[{"internalType":"bool","name":"result","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_idCollection","type":"address"},{"internalType":"uint256","name":"_idNFT","type":"uint256"},{"internalType":"address","name":"_buyer","type":"address"},{"internalType":"address","name":"_receiver","type":"address"}],"name":"buyKSM","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_idCollection","type":"address"},{"internalType":"uint256","name":"_idNFT","type":"uint256"}],"name":"cancelAsk","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_sender","type":"address"}],"name":"depositKSM","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"address","name":"_currencyCode","type":"address"},{"internalType":"address","name":"_idCollection","type":"address"},{"internalType":"uint256","name":"_idNFT","type":"uint256"},{"internalType":"uint8","name":"_active","type":"uint8"}],"name":"editAsk","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_idCollection","type":"address"},{"internalType":"uint256","name":"_idNFT","type":"uint256"}],"name":"getOrder","outputs":[{"components":[{"internalType":"uint256","name":"idNFT","type":"uint256"},{"internalType":"address","name":"currencyCode","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"time","type":"uint256"},{"internalType":"address","name":"idCollection","type":"address"},{"internalType":"address","name":"ownerAddr","type":"address"},{"internalType":"uint8","name":"flagActive","type":"uint8"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"tokenURI","type":"string"}],"internalType":"struct MarketPlace.Order","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOrdersLen","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"orders","outputs":[{"internalType":"uint256","name":"idNFT","type":"uint256"},{"internalType":"address","name":"currencyCode","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"time","type":"uint256"},{"internalType":"address","name":"idCollection","type":"address"},{"internalType":"address","name":"ownerAddr","type":"address"},{"internalType":"uint8","name":"flagActive","type":"uint8"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"tokenURI","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newEscrow","type":"address"}],"name":"setEscrow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_coin","type":"address"}],"name":"setNativeCoin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newEscrow","type":"address"}],"name":"setowner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_currencyCode","type":"address"},{"internalType":"address payable","name":"_sender","type":"address"}],"name":"withdraw","outputs":[{"internalType":"bool","name":"result","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_sender","type":"address"}],"name":"withdrawAllKSM","outputs":[{"internalType":"uint256","name":"lastBalance","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
\ No newline at end of file
deletedtests/src/eth/marketplace/MarketPlace.bindiffbeforeafterboth

no changes

modifiedtests/src/eth/marketplace/MarketPlace.soldiffbeforeafterboth
--- a/tests/src/eth/marketplace/MarketPlace.sol
+++ b/tests/src/eth/marketplace/MarketPlace.sol
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier:  Apache License
 pragma solidity >=0.8.0;
-import "../api/UniqueNFT.sol";
+import {UniqueNFT, Dummy, ERC165} from "../api/UniqueNFT.sol";
 
 // Inline
 interface ERC20Events {
@@ -52,8 +52,9 @@
 
 contract MarketPlace {
     struct Order {
+        
         uint256 idNFT;
-        address currencyCode; // UNIQ tokens as address address (1); wKSM
+        address currencyCode; // UNIQ tokens as address address (1); wKSM 
         uint256 price;
         uint256 time;
         address idCollection;
@@ -61,330 +62,353 @@
         uint8 flagActive;
         string name;
         string symbol;
-        string tokenURI;
+        string tokenURI;        
     }
-    Order[] public orders;
-    uint256 test;
-    mapping(address => uint256) public balanceKSM; //  [ownerAddr][currency] => [KSMs]
-    mapping(address => mapping(uint256 => uint256)) public asks; // [buyer][idCollection][idNFT] => idorder
+    Order[] public  orders;
+    uint test;
+    mapping (address => uint256) public balanceKSM;  //  [ownerAddr][currency] => [KSMs]
+    mapping (address => mapping (uint256 => uint256)) public  asks ; // [buyer][idCollection][idNFT] => idorder
+    mapping (address => mapping (uint => uint[])) public ordersbyNFT; // [addressCollection] =>idNFT =>idorder
+
+    mapping (address => uint[]) public asksbySeller; // [addressSeller] =>idorder
 
-    mapping(address => uint256[]) public asksbySeller; // [addressSeller] =>idorder
+    mapping (address =>bool) internal isEscrow;
 
-    address escrow;
+    //address escrow;
     address owner;
     address nativecoin;
 
-    constructor(address _escrow) {
-        escrow = _escrow;
+    // from abstract contract ReentrancyGuard 
+    // Booleans are more expensive than uint256 or any type that takes up a full
+    // word because each write operation emits an extra SLOAD to first read the
+    // slot's contents, replace the bits taken up by the boolean, and then write
+    // back. This is the compiler's defense against contract upgrades and
+    // pointer aliasing, and it cannot be disabled.
+
+    // The values being non-zero value makes deployment a bit more expensive,
+    // but in exchange the refund on every call to nonReentrant will be lower in
+    // amount. Since refunds are capped to a percentage of the total
+    // transaction's gas, it is best to keep them low in cases like this one, to
+    // increase the likelihood of the full refund coming into effect.
+    uint8 private constant _NOT_ENTERED = 1;
+    uint8 private constant _ENTERED = 2;
+
+    uint8 private _status;
+
+    struct NFT {
+        address  collection;
+        uint256 id;
+    }
+    
+     //function initialize() public initializer {
+   constructor () { // call setEscrow directly
         owner = msg.sender;
 
-        orders.push(
-            Order(0, address(0), 0, 0, address(0), address(0), 0, "", "", "")
-        );
+         orders.push(Order(        
+                    0,
+                    address(0),
+                    0,
+                    0,
+                    address(0),
+                    address(0),
+                    0, "","",""));
+         _status = _NOT_ENTERED;
+
     }
 
-    function setowner(address _newEscrow) public onlyOwner {
-        escrow = _newEscrow;
-    }
+    modifier nonReentrant() { // from abstract contract ReentrancyGuard 
+        // On the first call to nonReentrant, _notEntered will be true
+        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
 
-    function setEscrow(address _newEscrow) public onlyOwner {
-        escrow = _newEscrow;
-    }
+        // Any calls to nonReentrant after this point will fail
+        _status = _ENTERED;
 
-    function setNativeCoin(address _coin) public onlyOwner {
-        nativecoin = _coin;
+        _;
+
+        // By storing the original value once again, a refund is triggered (see
+        // https://eips.ethereum.org/EIPS/eip-2200)
+        _status = _NOT_ENTERED;
     }
 
-    modifier onlyEscrow() {
-        require(msg.sender == escrow, "Only escrow can");
+    modifier onlyEscrow () {
+        require(isEscrow [msg.sender] , "Only escrow can");
         _;
     }
 
-    modifier onlyOwner() {
+    modifier onlyOwner () {
         require(msg.sender == owner, "Only owner can");
         _;
     }
 
     /**
-     * Make bids (orders) to sell NFTs
-     */
+    * Make bids (orders) to sell NFTs 
+    */
 
-    receive() external payable {
-        revert(
-            "Can't accept payment without collection and IDs, use dApp to send"
-        );
+     
+    receive  () external payable  {
+     //   revert ("Can't accept payment without collection and IDs, use dApp to send");
     }
+    fallback () external payable {
+        revert ("No such function");
+    } 
 
-    fallback() external payable {
-        revert("No such function");
-    }
+    event AddedAsk (uint256 _price, 
+                    address  _currencyCode, 
+                    address _idCollection, 
+                    uint256 _idNFT,
+                    uint256 orderId
+                  );
+    event EditedAsk (uint256 _price, 
+                    address  _currencyCode, 
+                    address _idCollection, 
+                    uint256 _idNFT,
+                    uint8  _active,
+                    uint orderId);
 
-    event AddedAsk(
-        uint256 _price,
-        address _currencyCode,
-        address _idCollection,
-        uint256 _idNFT,
-        uint256 orderId
-    );
-    event EditedAsk(
-        uint256 _price,
-        address _currencyCode,
-        address _idCollection,
-        uint256 _idNFT,
-        uint8 _active,
-        uint256 orderId
-    );
+    event  CanceledAsk (address _idCollection, 
+                        uint256 _idNFT, 
+                        uint orderId
+                        );
+
+    event DepositedKSM (uint256 _amount,  address _sender);
+
+    event BoughtNFT4KSM (address _idCollection, uint256 _idNFT, uint orderID, uint orderPrice );
+
+    event BoughtNFT (address _idCollection, uint256 _idNFT, uint orderID, uint orderPrice );
+
+    event WithdrawnAllKSM (address _sender, uint256 balance); 
 
-    event CanceledAsk(address _idCollection, uint256 _idNFT, uint256 orderId);
+    event WithdrawnKSM (address _sender, uint256 balance); 
 
-    event DepositedKSM(uint256 _amount, address _sender);
+    event Withdrawn (uint256 _amount, address _currencyCode, address _sender);
+    
 
-    event BoughtNFT4KSM(
-        address _idCollection,
-        uint256 _idNFT,
-        uint256 orderID,
-        uint256 orderPrice
-    );
+   function setOwner  (address _newOwner) public onlyOwner {
+        owner = _newOwner;
+    }
 
-    event BoughtNFT(
-        address _idCollection,
-        uint256 _idNFT,
-        uint256 orderID,
-        uint256 orderPrice
-    );
+    function setEscrow  (address _escrow, bool _state) public onlyOwner returns (bool) {
+        if (isEscrow[_escrow] != _state)  {
+            isEscrow[_escrow] = _state;
+            return true;
+        }
+        return false;
+    }
 
-    event WithdrawnAllKSM(address _sender, uint256 balance);
+    function setNativeCoin  (address _coin) public onlyOwner {
+        nativecoin = _coin;
+    }
 
-    event Withdrawn(uint256 _amount, address _currencyCode, address _sender);
 
-    function addAsk(
-        uint256 _price,
-        address _currencyCode,
-        address _idCollection,
-        uint256 _idNFT
-    ) public {
-        //
+    function addAsk (uint256 _price, 
+                    address  _currencyCode, 
+                    address _idCollection, 
+                    uint256 _idNFT
+                  ) public  { //
         address ownerNFT = UniqueNFT(_idCollection).ownerOf(_idNFT);
-        require(ownerNFT == msg.sender, "Only token owner can make ask");
+        require (ownerNFT == msg.sender, "Only token owner can make ask");
         string memory nameNFT;
         string memory symbolNFT;
         string memory uriNFT;
         try UniqueNFT(_idCollection).name() returns (string memory name_) {
             nameNFT = name_;
-        } catch {
-            nameNFT = "";
         }
+        catch {
+            nameNFT="";
+        }   
         try UniqueNFT(_idCollection).symbol() returns (string memory symbol_) {
             symbolNFT = symbol_;
-        } catch {
-            symbolNFT = "";
         }
-        try UniqueNFT(_idCollection).tokenURI(_idNFT) returns (
-            string memory uri_
-        ) {
+        catch {
+            symbolNFT="";
+        }  
+        try UniqueNFT(_idCollection).tokenURI(_idNFT) returns (string memory uri_) {
             uriNFT = uri_;
-        } catch {
-            uriNFT = "";
         }
-        orders.push(
-            Order(
-                _idNFT,
-                _currencyCode,
-                _price,
-                block.timestamp,
-                _idCollection,
-                msg.sender,
-                1, // 1 = is active
-                nameNFT,
-                symbolNFT,
-                uriNFT
-            )
-        );
+        catch {
+            uriNFT="";
+        }        
+        orders.push(Order(        
+                    _idNFT,
+                    _currencyCode,
+                    _price,
+                    block.timestamp,
+                    _idCollection,
+                    msg.sender,
+                    1, // 1 = is active
+                    nameNFT, 
+                    symbolNFT,
+                    uriNFT
+             ));
+            
+            uint orderId = orders.length-1;
+            asks[_idCollection][_idNFT] = orderId;
+            asksbySeller[msg.sender].push(orderId);
+            UniqueNFT(_idCollection).transferFrom(msg.sender, address(this), _idNFT);
+            emit AddedAsk(_price, _currencyCode, _idCollection, _idNFT, orderId);     
+    }
 
-        uint256 orderId = orders.length - 1;
-        asks[_idCollection][_idNFT] = orderId;
-        asksbySeller[msg.sender].push(orderId);
-        UniqueNFT(_idCollection).transferFrom(
-            msg.sender,
-            address(this),
-            _idNFT
-        );
-        emit AddedAsk(_price, _currencyCode, _idCollection, _idNFT, orderId);
-    }
+    function editAsk (uint256 _price, 
+                    address  _currencyCode, 
+                    address _idCollection, 
+                    uint256 _idNFT,
+                    uint8  _active) public {
+        
 
-    function editAsk(
-        uint256 _price,
-        address _currencyCode,
-        address _idCollection,
-        uint256 _idNFT,
-        uint8 _active
-    ) public {
-        uint256 orderID = asks[_idCollection][_idNFT];
+        uint orderID =  asks[_idCollection][_idNFT];
 
-        require(
-            orders[orderID].ownerAddr == msg.sender,
-            "Only token owner can edit ask"
-        );
-        require(orders[orderID].flagActive != 0, "This ask is closed");
-        if (_price > 0) {
-            orders[orderID].price = _price;
+        require (orders[orderID].ownerAddr == msg.sender, "Only token owner can edit ask");
+        require (orders[orderID].flagActive != 0, "This ask is closed");
+        if (_price> 0 ) {
+            orders[orderID].price = _price ;  
         }
-
-        if (_currencyCode != address(0)) {
-            orders[orderID].currencyCode = _currencyCode;
+        
+        if (_currencyCode != address(0) ) {
+            orders[orderID].currencyCode = _currencyCode ;  
         }
 
         orders[orderID].time = block.timestamp;
         orders[orderID].flagActive = _active;
+        
+        emit EditedAsk(_price, _currencyCode, _idCollection, _idNFT, _active, orderID);
+        }
+        
 
-        emit EditedAsk(
-            _price,
-            _currencyCode,
-            _idCollection,
-            _idNFT,
-            _active,
-            orderID
-        );
-    }
+    function cancelAsk (address _idCollection, 
+                        uint256 _idNFT
+                        ) public {
 
-    function cancelAsk(address _idCollection, uint256 _idNFT) public {
-        uint256 orderID = asks[_idCollection][_idNFT];
+        uint orderID =  asks[_idCollection][_idNFT];
 
-        require(
-            orders[orderID].ownerAddr == msg.sender,
-            "Only token owner can edit ask"
-        );
-        require(orders[orderID].flagActive != 0, "This ask is closed");
+        require (orders[orderID].ownerAddr == msg.sender, "Only token owner can edit ask");
+        require (orders[orderID].flagActive != 0, "This ask is closed");
 
         orders[orderID].time = block.timestamp;
         orders[orderID].flagActive = 0;
-        UniqueNFT(_idCollection).transferFrom(
-            address(this),
-            orders[orderID].ownerAddr,
-            _idNFT
-        );
+        UniqueNFT(_idCollection).transferFrom(address(this),orders[orderID].ownerAddr, _idNFT);
         emit CanceledAsk(_idCollection, _idNFT, orderID);
-    }
+        }
+
 
-    function depositKSM(uint256 _amount, address _sender) public onlyEscrow {
+    function depositKSM (uint256 _amount,  address _sender) public onlyEscrow {
         balanceKSM[_sender] = balanceKSM[_sender] + _amount;
         emit DepositedKSM(_amount, _sender);
     }
 
-    function buyKSM(
-        address _idCollection,
-        uint256 _idNFT,
-        address _buyer,
-        address _receiver
-    ) public {
-        Order memory order = orders[asks[_idCollection][_idNFT]];
-        require(msg.sender == escrow || msg.sender == _buyer, "Only escrow or buyer can call buyKSM" );
+    function buyKSM (address _idCollection, uint256 _idNFT, address _buyer, address _receiver ) public {
+        
+        Order memory order = orders[ asks[_idCollection][_idNFT]];
+        require(isEscrow[msg.sender]  || msg.sender == _buyer, "Only escrow or buyer can call buyKSM" );
         //1. reduce balance
+
         balanceKSM[_buyer] = balanceKSM[_buyer] - order.price;
         balanceKSM[order.ownerAddr] = balanceKSM[order.ownerAddr] + order.price;
         // 2. close order
-        orders[asks[_idCollection][_idNFT]].flagActive = 0;
+        orders[ asks[_idCollection][_idNFT]].flagActive = 0;
         // 3. transfer NFT to buyer
         UniqueNFT(_idCollection).transferFrom(address(this), _receiver, _idNFT);
-        emit BoughtNFT4KSM(
-            _idCollection,
-            _idNFT,
-            asks[_idCollection][_idNFT],
-            order.price
-        );
+        emit BoughtNFT4KSM(_idCollection, _idNFT, asks[_idCollection][_idNFT], order.price);
+
     }
-
-    function buy(address _idCollection, uint256 _idNFT)
-        public
-        payable
-        returns (bool result)
-    {
-        //buing for UNQ like as ethers
-
-        Order memory order = orders[asks[_idCollection][_idNFT]];
+    function buy (address _idCollection, uint256 _idNFT ) public payable returns (bool result) { //buing for UNQ like as ethers 
+        
+        Order memory order = orders[asks[_idCollection][_idNFT]]; 
         //1. check sent amount and send to seller
-        require(
-            msg.value == order.price,
-            "Not right amount sent, have to be equal price"
-        );
+        require (msg.value == order.price, "Not right amount sent, have to be equal price" );     
         // 2. close order
-        orders[asks[_idCollection][_idNFT]].flagActive = 0;
-
+        orders[ asks[_idCollection][_idNFT]].flagActive = 0;
+        
         // 3. transfer NFT to buyer
-        UniqueNFT(_idCollection).transferFrom(
-            address(this),
-            msg.sender,
-            _idNFT
-        );
+        UniqueNFT(_idCollection).transferFrom(address(this), msg.sender, _idNFT);
         //uint balance  = address(this).balance;
-        result = payable(order.ownerAddr).send(order.price);
-        emit BoughtNFT(
-            _idCollection,
-            _idNFT,
-            asks[_idCollection][_idNFT],
-            order.price
-        );
+        result = payable(order.ownerAddr).send (order.price); 
+        emit BoughtNFT(_idCollection, _idNFT, asks[_idCollection][_idNFT], order.price);
+        
     }
 
-    /*
-        function buyOther (address _idCollection, uint256 _idNFT, address _currencyCode, uint _amount ) public  { //buy for sny token if seller wants
+/* 
+    function buyOther (address _idCollection, uint256 _idNFT, address _currencyCode, uint _amount ) public  { //buy for sny token if seller wants
+        
+        Order memory order = orders[ asks[_idCollection][_idNFT]];
+        //1. check sent amount and transfer from buyer to seller
+        require (order.price == _amount && order.currencyCode == _currencyCode, "Not right amount or currency sent, have to be equal currency and price" );
+        // !!! transfer have to be approved to marketplace!
+        UniqueFungible(order.currencyCode).transferFrom(msg.sender, address(this), order.price); //to not disclojure buyer's address 
+        UniqueFungible(order.currencyCode).transfer(order.ownerAddr, order.price);
+        // 2. close order
+        orders[ asks[_idCollection][_idNFT]].flagActive = 0;
+        // 3. transfer NFT to buyer
+        UniqueNFT(_idCollection).transferFrom(address(this), msg.sender, _idNFT);
 
-            Order memory order = orders[ asks[_idCollection][_idNFT]];
-            //1. check sent amount and transfer from buyer to seller
-            require (order.price == _amount && order.currencyCode == _currencyCode, "Not right amount or currency sent, have to be equal currency and price" );
-            // !!! transfer have to be approved to marketplace!
-            IERC20(order.currencyCode).transferFrom(msg.sender, address(this), order.price); //to not disclojure buyer's address
-            IERC20(order.currencyCode).transfer(order.ownerAddr, order.price);
-            // 2. close order
-            orders[ asks[_idCollection][_idNFT]].flagActive = 0;
-            // 3. transfer NFT to buyer
-            IERC721ext(_idCollection).transferFrom(address(this), msg.sender, _idNFT);
 
+    }
+ */
 
-        }
-    */
+    function withdrawAllKSM (address _sender) public  nonReentrant returns (uint lastBalance ){
+        require(isEscrow[msg.sender]  || msg.sender == _sender, "Only escrow or balance owner can withdraw all KSM" );
 
-    function withdrawAllKSM(address _sender)
-        public
-        onlyEscrow
-        returns (uint256 lastBalance)
-    {
         lastBalance = balanceKSM[_sender];
-        balanceKSM[_sender] = 0;
+        balanceKSM[_sender] =0;
         emit WithdrawnAllKSM(_sender, lastBalance);
     }
 
-    function withdraw(
-        uint256 _amount,
-        address _currencyCode,
-        address payable _sender
-    ) public onlyOwner returns (bool result) {
-        if (_currencyCode != nativecoin) {
-            //erc20 compat. tokens on UNIQUE chain
-            // uint balance = IERC20(_currencyCode).balanceOf(address(this));
+    function withdrawKSM (uint _amount, address _sender) onlyEscrow public {
+        balanceKSM[_sender] = balanceKSM[_sender] - _amount;
+        emit WithdrawnKSM(_sender, balanceKSM[_sender]);
+        
+    }
+
+    function withdraw (uint256 _amount, address _currencyCode) public  nonReentrant returns (bool result ){ //onlyOwner
+        address payable _sender = payable( msg.sender);
+        if (_currencyCode != nativecoin ) { //erc20 compat. tokens on UNIQUE chain
+            // uint balance = UniqueFungible(_currencyCode).balanceOf(address(this));
             UniqueFungible(_currencyCode).transfer(_sender, _amount);
         } else {
             // uint balance  = address(this).balance;
 
-            result = (_sender).send(_amount); // for UNQ like as ethers
+            result =  (_sender).send(_amount); // for UNQ like as ethers 
         }
         emit Withdrawn(_amount, _currencyCode, _sender);
         return result;
+
     }
 
-    // event GettedOrder(uint , Order);
-    function getOrder(address _idCollection, uint256 _idNFT)
-        public
-        view
-        returns (Order memory)
-    {
-        uint256 orderId = asks[_idCollection][_idNFT];
+    
+   // event GettedOrder(uint , Order);
+    function getOrder (address _idCollection, uint256 _idNFT) public view returns (Order memory) {
+        uint orderId = asks[_idCollection][_idNFT];
         Order memory order = orders[orderId];
-        //       emit GettedOrder (orderId, order);
+ //       emit GettedOrder (orderId, order);
         return order;
     }
 
-    function getOrdersLen() public view returns (uint256) {
+    function getOrdersLen () public view returns (uint) {
         return orders.length;
     }
+
+    function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) public pure returns(bytes4) {
+            return bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"));
+        }
+     
+    //TODO make destructing function to return all 
+    function terminate(address[] calldata tokens, NFT[] calldata nfts) public onlyOwner {
+    // Transfer tokens to owner (TODO: error handling)
+        for (uint i = 0; i < tokens.length; i++) {
+            address addr = tokens[i];
+            UniqueFungible token = UniqueFungible(addr);
+            uint256 balance = token.balanceOf(address(this));
+            token.transfer(owner, balance);
+        }
+        for (uint i = 0; i < nfts.length; i++) {
+            address addr = nfts[i].collection;
+            UniqueNFT token = UniqueNFT(addr);
+            token.transferFrom(address(this), owner, nfts[i].id);
+        }    
+    // Transfer Eth to owner and terminate contract
+        address payable owner1 = payable (owner);
+        uint balance = address(this).balance;
+        owner1.transfer(balance);
+        
+    } 
+    
 }
modifiedtests/src/eth/marketplace/marketplace.test.tsdiffbeforeafterboth
--- a/tests/src/eth/marketplace/marketplace.test.ts
+++ b/tests/src/eth/marketplace/marketplace.test.ts
@@ -46,13 +46,8 @@
   });
 
   itEth('With UNQ', async ({helper}) => {
-    const web3 = helper.getWeb3();
     const matcherOwner = await helper.eth.createAccountWithBalance(donor);
-    const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlace.abi`)).toString()), undefined, {
-      from: matcherOwner,
-      gas: helper.eth.DEFAULT_GAS,
-    });
-    const matcher = await matcherContract.deploy({data: (await readFile(`${__dirname}/MarketPlace.bin`)).toString(), arguments:[matcherOwner]}).send({from: matcherOwner});
+    const matcher = await helper.ethContract.deployByCode(matcherOwner, 'MarketPlace', (await readFile(`${__dirname}/MarketPlace.sol`)).toString(), [{solPath: 'api/UniqueNFT.sol', fsPath: `${__dirname}/../api/UniqueNFT.sol`}], helper.eth.DEFAULT_GAS * 2);
 
     const sponsor = await helper.eth.createAccountWithBalance(donor);
     const helpers = helper.ethNativeContract.contractHelpers(matcherOwner);
@@ -103,17 +98,12 @@
   });
 
   itEth('With escrow', async ({helper}) => {
-    const web3 = helper.getWeb3();
     const matcherOwner = await helper.eth.createAccountWithBalance(donor);
-    const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlace.abi`)).toString()), undefined, {
-      from: matcherOwner,
-      gas: helper.eth.DEFAULT_GAS,
-    });
-    const matcher = await matcherContract.deploy({data: (await readFile(`${__dirname}/MarketPlace.bin`)).toString(), arguments: [matcherOwner]}).send({from: matcherOwner, gas: 10000000});
+    const matcher = await helper.ethContract.deployByCode(matcherOwner, 'MarketPlace', (await readFile(`${__dirname}/MarketPlace.sol`)).toString(), [{solPath: 'api/UniqueNFT.sol', fsPath: `${__dirname}/../api/UniqueNFT.sol`}], helper.eth.DEFAULT_GAS * 2);
 
     const sponsor = await helper.eth.createAccountWithBalance(donor);
     const escrow = await helper.eth.createAccountWithBalance(donor);
-    await matcher.methods.setEscrow(escrow).send({from: matcherOwner});
+    await matcher.methods.setEscrow(escrow, true).send({from: matcherOwner});
     const helpers = helper.ethNativeContract.contractHelpers(matcherOwner);
     await helpers.methods.setSponsoringMode(matcher.options.address, SponsoringMode.Allowlisted).send({from: matcherOwner});
     await helpers.methods.setSponsoringRateLimit(matcher.options.address, 1).send({from: matcherOwner});
@@ -172,13 +162,8 @@
   });
 
   itEth('Sell tokens from substrate user via EVM contract', async ({helper}) => {
-    const web3 = helper.getWeb3();
     const matcherOwner = await helper.eth.createAccountWithBalance(donor);
-    const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlace.abi`)).toString()), undefined, {
-      from: matcherOwner,
-      gas: helper.eth.DEFAULT_GAS,
-    });
-    const matcher = await matcherContract.deploy({data: (await readFile(`${__dirname}/MarketPlace.bin`)).toString(), arguments:[matcherOwner]}).send({from: matcherOwner});
+    const matcher = await helper.ethContract.deployByCode(matcherOwner, 'MarketPlace', (await readFile(`${__dirname}/MarketPlace.sol`)).toString(), [{solPath: 'api/UniqueNFT.sol', fsPath: `${__dirname}/../api/UniqueNFT.sol`}], helper.eth.DEFAULT_GAS * 2);
 
     await helper.eth.transferBalanceFromSubstrate(donor, matcher.options.address);
 
modifiedtests/src/eth/util/playgrounds/unique.dev.tsdiffbeforeafterboth
--- a/tests/src/eth/util/playgrounds/unique.dev.ts
+++ b/tests/src/eth/util/playgrounds/unique.dev.ts
@@ -79,17 +79,17 @@
     };
   }
 
-  async deployByCode(signer: string, name: string, src: string, imports?: ContractImports[]): Promise<Contract> {
+  async deployByCode(signer: string, name: string, src: string, imports?: ContractImports[], gas?: number): Promise<Contract> {
     const compiledContract = await this.compile(name, src, imports);
-    return this.deployByAbi(signer, compiledContract.abi, compiledContract.object);
+    return this.deployByAbi(signer, compiledContract.abi, compiledContract.object, gas);
   }
 
-  async deployByAbi(signer: string, abi: any, object: string): Promise<Contract> {
+  async deployByAbi(signer: string, abi: any, object: string, gas?: number): Promise<Contract> {
     const web3 = this.helper.getWeb3();
     const contract = new web3.eth.Contract(abi, undefined, {
       data: object,
       from: signer,
-      gas: this.helper.eth.DEFAULT_GAS,
+      gas: gas ?? this.helper.eth.DEFAULT_GAS,
     });
     return await contract.deploy({data: object}).send({from: signer});
   }