difftreelog
MarketPlace.sol from unique-marketplace
in: master
5 files changed
tests/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
tests/src/eth/marketplace/MarketPlace.bindiffbeforeafterbothno changes
tests/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);
+
+ }
+
}
tests/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);
tests/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});
}