# ERC721 Exercise 2

## Intro
OpenOcean wants to become the world's largest digital marketplace for crypto collectibles and non-fungible tokens (NFTs).

Users should be able to buy, sell, and discover exclusive digital items.


You've been given the task to develop their marketplace smart contract.
What a terrific opportunity to improve your skills in ERC721 tokens, right? ;)

## Accounts
* 0 - Deployer
* 1 - User1
* 2 - User2
* 3 - User3

## Tasks

### Task 1
**Complete the `OpenOcean.sol` smart contract, implement all the open TODOs**
 1. Create a `maxPrice` constant of uint256, 100 ether (maximum NFT listing price)
 2. Create an `Item` struct which represents an erc721 item that is on sale.
 3. The struct should have the following data: 
    1. itemId (uint256)
    2. collection contract (address)
    3. tokenId (uint256)
    4. price (uint256)
    5. seller (address payable)
    6. isSold (bool)
 4. Create a `itemsCounter` state variable (uint256)
 5. Create an `listedItems` mapping which maps between `itemId` (uint256) to `Item` (struct).
 6. Create an external `listItem` function which allows users to list their nft in the marketplace. The function should receive the collection contract address, the tokenId, and the price it will be listed for:
    1. Make sure the parameters are correct
    2. Increment `itemsCounter`
    3. Transfer token from the sender to the contract
    4. Add item to the `listedItems` mapping
 7. Create an external payable `purchase` function which receives `itemId` and allows someone to purchase the item:
    1. Check that the item exists and not sold
    2. Check that enough ETH was paid
    3. Change item status to "sold"
    4. Transfer NFT to buyer
    5. Transfer ETH to seller


### Task 2
**You will use the `DummyERC721.sol` contract to test your Marketplace**

#### Deployment and listings tests
1. Deploy the marketplace contract from the deployer account
2. From user1: List Crypto Cuties token IDs 1 - 10, for 5 ETH each 
   1. Test that the `itemsCounter` is 10
   2. Test that the marketplace contract owns 10 Crypto Cuties NFTs
   3. Check that all the parameters of the last item that was listed are correct   
3. From user3: List Rare Boobles token IDs 1 - 5, for 7 ETH each 
   1. Test that the `itemsCounter` is 15
   2. Test that the marketplace contract owns 5 Rare Boobles NFTs
   3. Check that all the parameters of the last item that was listed are correct

#### Purchases tests
1. From User2:
   1. Try to purchase itemId 100 (doesn't exist), and make sure the transaction is reverted
   2. Try to purchase item number 3, without providing any ETH, and make sure the transaction is reverted
   3. Try to purchase item number 3 with the correct amount of ETH, and make sure the transaction goes through
   4. Try to purchase item number 3 again, and make sure the transaction is reverted with the relevant error message
   5. Make sure that User2 owns item number 3
   6. Make sure that the User1 got the right amount of ETH for the sale
   7. Try to purchase item number 11 with the correct amount of ETH, make sure the transaction goes through
   8. Make sure User2 owns item number 11
   9. Make sure that User3 got the right amount of ETH for the sale



## Links that might be useful
1. ERC721 Standard on Ethereum Website
https://eips.ethereum.org/EIPS/eip-721
2. ERC721 Source code on Github
https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol
3. Hardhat Tests
https://hardhat.org/tutorial/testing-contracts