-
Notifications
You must be signed in to change notification settings - Fork 65
/
Marketplace.sol
94 lines (76 loc) · 2.43 KB
/
Marketplace.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
contract Marketplace {
enum OrderStatus {
ACTIVE,
CANCELED,
EXECUTED
}
struct SellOrder {
address nftContractAddress;
uint256 tokenId;
address creator;
uint256 price;
OrderStatus status;
}
SellOrder[] private sellOrders;
function postSellOrder(
address nftContractAddress,
uint256 tokenId,
uint256 price
) external {
// Check if tokenId is owned by tx sender
IERC721 nftContract = IERC721(nftContractAddress);
require(nftContract.ownerOf(tokenId) == msg.sender);
// Transfer NFT token to the contract address
// Sender needs to approve the transfer before posting sell order
nftContract.transferFrom(msg.sender, address(this), tokenId);
// Save order in the sellOrders mapping
sellOrders.push(
SellOrder(
nftContractAddress,
tokenId,
msg.sender,
price,
OrderStatus.ACTIVE
)
);
}
function cancelOrder(uint256 orderId) external {
SellOrder storage order = sellOrders[orderId];
// Only order creator can cancel the order
require(order.creator == msg.sender);
// Transfer NFT back to order creator
IERC721 nftContract = IERC721(order.nftContractAddress);
nftContract.transferFrom(address(this), msg.sender, order.tokenId);
// Update order status
order.status = OrderStatus.CANCELED;
}
function buy(uint256 orderId) external payable {
// Order must exist and be in the active state
SellOrder storage order = sellOrders[orderId];
require(order.status == OrderStatus.ACTIVE);
// Check transfered ETH value
uint256 expectedEthAmount = _getPriceFromOrder(order);
require(expectedEthAmount <= msg.value);
// Transfer NFT to buyer
IERC721 nftContract = IERC721(order.nftContractAddress);
nftContract.transferFrom(address(this), msg.sender, order.tokenId);
// Mark order as executed
order.status = OrderStatus.EXECUTED;
}
function _getPriceFromOrder(
SellOrder memory order
) internal view virtual returns (uint256) {
return order.price;
}
// Getters for the UI
function getPrice(uint256 orderId) public view returns (uint256) {
SellOrder storage order = sellOrders[orderId];
return _getPriceFromOrder(order);
}
function getAllOrders() public view returns (SellOrder[] memory) {
return sellOrders;
}
}