> For the complete documentation index, see [llms.txt](https://docs.autentica.io/whitepaper/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.autentica.io/whitepaper/blockchain/nft-marketplace.md).

# NFT Marketplace

### Overview

[NFT Marketplace](https://github.com/AutenticaCrypto/smart-contracts/blob/main/contracts/NFTMarketplace.sol) is a decentralized NFT exchange that allows users to buy any [ERC-721](https://eips.ethereum.org/EIPS/eip-721) compatible NFTs with coins and tokens.

These are the goals we had in mind when designing the protocol:

* Make it as accessible as possible to sellers by not requiring them to perform blockchain transactions when listing their NFTs for sale, hence saving on gas fees.
* Pay royalties by implementing the [ERC-2981](https://eips.ethereum.org/EIPS/eip-2981) standard as well as our own solution detailed in the [IERC721Autentica](https://github.com/AutenticaCrypto/smart-contracts/blob/main/contracts/IERC721Autentica.sol) interface.
* Temporarily suspend the smart contract in the event of an emergency.

```
                                                                                                                                           
                                        ,-.                                                                                                
                                        `-'                                                                                                
                                        /|\                                                                                                
                          ,-.            |              ,-.                                                                                
                          `-'           / \             `-'                                                                                
                          /|\                           /|\                                                                                
    ,-.                    |         Investor            |                                                                                 
    `-'                   / \            ^              / \                                                                                
    /|\                                  |                                                                                                 
     |                  Creator         pay         Autentica                                                                              
    / \                    ^          investor           ^                                                                           ,-.   
                           |            [2]              |                                                                           `-'   
  Seller                   |    pay      |      pay      |                                                                           /|\   
     ^                     +- creator ---+-- Autentica --+                                                                            |    
     |                          [1]      |                            $$$$$$$$$$$$$$$$$$$$                                           / \   
     |                                   |                            $                  $                                                 
     |                                   |                     +------$  tradeForCoins   $<------+                                  Buyer ^
     |                   +------------------------------+      |      $                  $       |        +-----------------+         |   |
     |                   |                              |      |      $$$$$$$$$$$$$$$$$$$$       |        |                 |         |   |
     |                   |                              |      |                                 +--------| canPerformTrade |<--------+   |
     |                   |                              |      |                                 |        |                 |             |
     +--- pay owner -----|       NFT Marketplace        |<-----+      $$$$$$$$$$$$$$$$$$$$       |        +-----------------+             |
     |                   |                              |      |      $                  $       |                                        |
     |                   |                              |      +------$  tradeForTokens  $<------+                                        |
     |                   |                              |             $                  $                                                |
     |                   +--------------------------+---+             $$$$$$$$$$$$$$$$$$$$                                                |
     |                                   ^          |                                                                                     |
     |                                   |          |                                                                                     |
     +----approves marketplace ----------+          +---------------------------------------  sends NFT  ---------------------------------+
                                                                                                                                           
                                                                                                                                           
     * [1] the creator is payed if he is no longer the owner and the royalties are set to >0%                                              
     * [2] the investor is payed from creator's proceeds only if the NFT was minted by an investor                                         
```

### How it Works

The smart contract's main public functions are `canPerformTrade`, `tradeForCoins` and `tradeForTokens`. All of these functions are meant to be called by the *Buyer* via [Autentica Marketplace](https://autentica.market/). The first function called `canPerformTrade` is used to check if the user is allowed to perform a trade using the specified parameters, while the remaining two functions, `tradeForCoins` and `tradeForTokens` are used to perform an actual trade using coins (the native cryptocurrency of the platform, i.e.: ETH) or tokens (i.e.: AUT/USDT/USDC).

Behind the scenes, `tradeForCoins` and `tradeForTokens` functions are actually calling `canPerformTrade` and determine whether or not the user is allowed to perform a trade with the specified parameters, but the reason for why `canPerformTrade` is exposed publicly is to allow the user to check if the trade is possible without actually performing it. This avoids having to pay gas fees if the transaction fails due to unmet conditions.

### Functions

**`canPerformTrade` is executed to check if the user is allowed to perform a trade using the specified parameters.**

```
/**
 * @notice Validate the trade.
 *
 * @param collection The ERC-721 smart contract.
 * @param tokenId The unique identifier of the ERC-721 token within the `collection` smart contract.
 * @param price The price of the NFT in `token` tokens.
 * @param currency The type of currency (ERC-20 or native currency)
 * @param buyer Buyer address.
 * @param marketplaceFee Marketplace fee.
 * @param signature ECDSA signature.
 *
 */
 function canPerformTrade(
    address collection,
    uint256 tokenId,
    uint256 price,
    address currency,
    address buyer,
    uint256 marketplaceFee,
    Signature calldata signature
 ) public view returns (bool)
```

This function validates the following conditions:

* The smart contract is not paused;
* The `collection` smart contract is a valid ERC-721 smart contract;
* The owner approved this smart contract to transfer the NFT identified by `tokenId` on their behalf;
* The royalty fee for the creator and `marketplaceFee` do not exceed 100%;
* The ECDSA `signature` that encodes all these parameters and a few others has been signed by an authorized user.

#### **`tradeForCoins`** is used to perform a trade using coins (the native cryptocurrency of the platform, i.e.: ETH).

```
/**
 * @notice Trades an NFT for a given amount of coins (the native cryptocurrency of the platform, i.e.: ETH).
 *
 * @param collection The ERC-721 smart contract.
 * @param tokenId The unique identifier of the ERC-721 token within the `collection` smart contract.
 * @param price The price of the NFT in coins.
 * @param buyer Buyer address.
 * @param marketplaceFee Marketplace fee.
 * @param signature ECDSA signature.
 *
 * @dev Requirements
 *
 * - The `collection` smart contract must be an ERC-721 smart contract.
 * - The owner of the NFT identified by `tokenId` within the `collection` smart contract must have approved
 *   this smart contract to manage its NFTs.
 * - The `price` and `msg.value` must be equal.
 * - The sum of all the fees cannot be greater than 100%.
 * - The ECDSA signature must be signed by someone with the admin or operator role.
 */
 function tradeForCoins(
    address collection,
    uint256 tokenId,
    uint256 price,
    address buyer,
    uint256 marketplaceFee,
    Signature calldata signature
 ) external payable nonReentrant
```

This function performs the following actions:

* Guards against reentrancy;
* Executes `canPerformTrade` to validate the parameters;
* Sends the proceeds to each party involved if the amount is greater than zero:
  * *Owner*: The owner of the NFT;
  * *Investor*:
    * The investor who minted the NFT on behalf of the creator.
    * **Note**: The investor is payed from the proceeds of the creator.
  * *Creator*: The creator of the NFT if the royalty fee is greater than 0% and the creator is no longer the owner.
  * *Marketplace*: The Autentica Marketplace.
* Transfers the NFT to the buyer.
* Emits the `TradedForCoins` event.

#### **`tradeForTokens`** is used to perform a trade using tokens (i.e. : AUT/USDT/USDC).

```
/**
 * @notice Trades an NFT for a given amount of ERC-20 tokens (i.e.: AUT/USDT/USDC).
 *
 * @param collection The ERC-721 smart contract.
 * @param tokenId The unique identifier of the ERC-721 token within the `collection` smart contract.
 * @param price The price of the NFT in `token` tokens.
 * @param token The ERC-20 smart contract.
 * @param buyer Buyer address.
 * @param marketplaceFee Marketplace fee.
 * @param signature ECDSA signature.
 *
 * Requirements:
 *
 * - The `collection` smart contract must be an ERC-721 smart contract.
 * - The owner of the NFT identified by `tokenId` within the `collection` smart contract must have approved
 *   this smart contract to manage its NFTs.
 * - The sum of all the fees cannot be greater than 100%.
 * - The ECDSA signature must be signed by someone with the admin or operator role.
 */
 function tradeForTokens(
    address collection,
    uint256 tokenId,
    uint256 price,
    address token,
    address buyer,
    uint256 marketplaceFee,
    Signature calldata signature
 ) external nonReentrant
```

This function performs the following actions:

* Guards against reentrancy;
* Validates that the ERC-20 `token` address is allowed to be used for trading;
* Executes `canPerformTrade` to validate the parameters;
* Sends the proceeds to each party involved if the amount is greater than zero:
  * *Owner*: The owner of the NFT;
  * *Investor*:
    * The investor who minted the NFT on behalf of the creator.
    * **Note**: The investor is payed from the proceeds of the creator.
  * *Creator*: The creator of the NFT if the royalty fee is greater than 0% and the creator is no longer the owner.
  * *Marketplace*: The Autentica Marketplace.
* Transfers the NFT to the buyer.
* Emits the `TradedForTokens` event.

### Events

#### **`TradedForCoins`** is emitted when a trade is performed using coins (the native cryptocurrency of the platform, i.e. : ETH).

```
/**
 * @dev Emitted when a trade occured between the `seller` (the owner of the ERC-721 token
 * represented by `tokenId` within the `collection` smart contract) and `buyer` which
 * payed the specified `price` in coins (the native cryptocurrency of the platform, i.e.: ETH).
 */
 event TradedForCoins(
    address indexed collection,
    uint256 indexed tokenId,
    address indexed seller,
    address buyer,
    uint256 price,
    uint256 ownerProceeds,
    uint256 creatorProceeds,
    uint256 investorProceeds
 );
```

#### **`TradedForTokens`** is emitted when a trade is performed using tokens (i.e. : AUT/USDT/USDC).

```
/**
 * @dev Emitted when a trade occured between the `seller` (the owner of the ERC-721 token
 * represented by `tokenId` within the `collection` smart contract) and `buyer` which
 * payed the specified `price` in tokens that are represented by the `token`
 * ERC-20 smart contract address.
 */
 event TradedForTokens(
    address indexed collection,
    uint256 indexed tokenId,
    address indexed seller,
    address buyer,
    address token,
    uint256 price,
    uint256 ownerProceeds,
    uint256 creatorProceeds,
    uint256 investorProceeds
 );
```

### Source Code

The source code for the smart contract can be found in the [NFTMarketplace.sol](https://github.com/AutenticaCrypto/smart-contracts/blob/main/contracts/NFTMarketplace.sol) file located in the `contracts` folder within our [smart-contracts](https://github.com/AutenticaCrypto/smart-contracts) repository.

### Deployments

| Network                       | Address                                                                                                                       |
| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| Ethereum                      | [0xc731d111023b11EB39606B672Be35f20C6D88Af1](https://etherscan.io/address/0xc731d111023b11eb39606b672be35f20c6d88af1)         |
| Binance Smart Chain           | [0x1a224a1a77f76aac623571408c45789a173314c8](https://bscscan.com/address/0x1a224a1a77f76aac623571408c45789a173314c8)          |
| Ethereum (Rinkeby)            | [0x12774EAd954F19DDe4142462C22E05F19452d320](https://rinkeby.etherscan.io/address/0x12774EAd954F19DDe4142462C22E05F19452d320) |
| Binance Smart Chain (testnet) | [0x621866d04C82Fbec31b1C67c5E4FAa904584CaFC](https://testnet.bscscan.com/address/0x621866d04C82Fbec31b1C67c5E4FAa904584CaFC)  |
