1
1
// SPDX-License-Identifier: MIT
2
2
pragma solidity ^ 0.8.21 ;
3
3
4
- import "../34_ERC721/IERC721.sol " ;
5
- import "../34_ERC721/IERC721Receiver.sol " ;
6
- import "../34_ERC721/WTFApe.sol " ;
4
+ import "../../../ 34_ERC721/IERC721.sol " ;
5
+ import "../../../ 34_ERC721/IERC721Receiver.sol " ;
6
+ import "../../../ 34_ERC721/WTFApe.sol " ;
7
7
8
8
contract NFTSwap is IERC721Receiver {
9
9
event List (
@@ -30,96 +30,95 @@ contract NFTSwap is IERC721Receiver {
30
30
uint256 newPrice
31
31
);
32
32
33
- // Definindo a estrutura 'order'
34
33
struct Order {
35
34
address owner;
36
35
uint256 price;
37
36
}
38
- // Mapeamento de Pedido NFT
37
+
39
38
mapping (address => mapping (uint256 => Order)) public nftList;
40
39
41
40
fallback () external payable {}
42
41
43
- // Venda pendente: O vendedor listou um NFT, com o endereço do contrato _nftAddr, tokenId _tokenId e preço _price em Ethereum (unidade wei).
44
42
function list (address _nftAddr , uint256 _tokenId , uint256 _price ) public {
45
- // Declaring variable for IERC721 interface contract
46
- // Contrato autorizado
47
- // Preço maior que 0
48
-
49
- //Definir o detentor e o preço do NF
50
- _order.owner = msg .sender ;
51
- _order.price = _price;
52
- // Transferir NFT para um contrato.
43
+ require (_price > 0 , "Price must be greater than 0 " );
44
+
45
+ IERC721 _nft = IERC721 (_nftAddr);
46
+ require (
47
+ _nft.ownerOf (_tokenId) == msg .sender ,
48
+ "Only the owner can list the NFT "
49
+ );
50
+ require (
51
+ _nft.getApproved (_tokenId) == address (this ),
52
+ "Contract is not approved to transfer this NFT "
53
+ );
54
+
55
+ nftList[_nftAddr][_tokenId] = Order (msg .sender , _price);
53
56
_nft.safeTransferFrom (msg .sender , address (this ), _tokenId);
54
57
55
- // Liberar evento de List
56
58
emit List (msg .sender , _nftAddr, _tokenId, _price);
57
59
}
58
60
59
- // Compra: O comprador adquire um NFT, com contrato _nftAddr e tokenId _tokenId, ao chamar a função, é necessário fornecer ETH.
60
61
function purchase (address _nftAddr , uint256 _tokenId ) public payable {
61
- // Obter Pedido
62
- // O preço do NFT é maior que 0
63
- // O preço de compra é maior do que o preço de etiqueta
64
- // Declaring variable for IERC721 interface contract
62
+ Order memory order = nftList[_nftAddr][_tokenId];
63
+ require (order.price > 0 , " NFT is not listed for sale " );
64
+ require ( msg . value >= order.price, " Insufficient ETH to purchase NFT " );
65
+
65
66
IERC721 _nft = IERC721 (_nftAddr);
66
- // NFT está presente no contrato.
67
+ require (
68
+ _nft.ownerOf (_tokenId) == address (this ),
69
+ "NFT is not in the contract "
70
+ );
71
+
72
+ delete nftList[_nftAddr][_tokenId];
67
73
68
- // Transferir o NFT para o comprador
69
74
_nft.safeTransferFrom (address (this ), msg .sender , _tokenId);
70
- // Transferir ETH para o vendedor e reembolsar o comprador com o ETH excedente
71
- payable (_order.owner).transfer (_order.price);
72
- payable (msg .sender ).transfer (msg .value - _order.price);
75
+ payable (order.owner).transfer (order.price);
73
76
74
- // Remover pedido
77
+ if (msg .value > order.price) {
78
+ payable (msg .sender ).transfer (msg .value - order.price);
79
+ }
75
80
76
- // Liberar evento de compra
77
- emit Purchase (msg .sender , _nftAddr, _tokenId, _order.price);
81
+ emit Purchase (msg .sender , _nftAddr, _tokenId, order.price);
78
82
}
79
83
80
- // Cancelar pedido: O vendedor cancela a ordem.
81
84
function revoke (address _nftAddr , uint256 _tokenId ) public {
82
- // Obter Pedido
83
- // Deve ser iniciado pelo titular
84
- // Declaring variable for IERC721 interface contract
85
+ Order memory order = nftList[_nftAddr][_tokenId];
86
+ require (order.owner == msg . sender , " You are not the owner of this NFT " );
87
+
85
88
IERC721 _nft = IERC721 (_nftAddr);
86
- // NFT está presente no contrato.
89
+ require (
90
+ _nft.ownerOf (_tokenId) == address (this ),
91
+ "NFT is not in the contract "
92
+ );
93
+
94
+ delete nftList[_nftAddr][_tokenId];
87
95
88
- // Transferir o NFT para o vendedor.
89
96
_nft.safeTransferFrom (address (this ), msg .sender , _tokenId);
90
- // Remover pedido
91
97
92
- // Liberar o evento Revoke
93
98
emit Revoke (msg .sender , _nftAddr, _tokenId);
94
99
}
95
100
96
- // Ajuste de preço: o vendedor ajusta o preço do pedido pendente
97
101
function update (
98
102
address _nftAddr ,
99
103
uint256 _tokenId ,
100
104
uint256 _newPrice
101
105
) public {
102
- // O preço do NFT é maior que 0
103
- // Obter Pedido
104
- // Deve ser iniciado pelo titular
105
- // Declaring variable for IERC721 interface contract
106
- IERC721 _nft = IERC721 (_nftAddr);
107
- // NFT está presente no contrato.
106
+ require (_newPrice > 0 , "Price must be greater than 0 " );
107
+
108
+ Order storage order = nftList[_nftAddr][_tokenId];
109
+ require (order.owner == msg .sender , "You are not the owner of this NFT " );
108
110
109
- // Ajustar o preço do NFT
110
- _order.price = _newPrice;
111
+ order.price = _newPrice;
111
112
112
- // Liberar evento de atualização
113
113
emit Update (msg .sender , _nftAddr, _tokenId, _newPrice);
114
114
}
115
115
116
- // Implemente o onERC721Received do {IERC721Receiver} para receber tokens ERC721
117
116
function onERC721Received (
118
- address operator ,
119
- address from ,
120
- uint tokenId ,
121
- bytes calldata data
122
- ) external override returns (bytes4 ) {
117
+ address ,
118
+ address ,
119
+ uint256 ,
120
+ bytes calldata
121
+ ) external pure override returns (bytes4 ) {
123
122
return IERC721Receiver .onERC721Received.selector ;
124
123
}
125
124
}
0 commit comments