Mint-Gold-Dust / v2-contracts

0 stars 0 forks source link

Auction #48

Closed luizoamorimgd closed 1 year ago

luizoamorimgd commented 1 year ago

This PR is creating a new structure for Mint Gold Dust smart contract

The main goal of this branch was add the auction functionality for our platform. But after raise some requirements and had analysed the code, I though better to break the Marketplace smart contract in more contracts that we can bring some good patterns like:

So now our structure have 6 smart contracts:

image

MGDCompany.sol

This smart contract is responsible by the functionalities related with MGD Management. Like:

MGDnft.sol

This smart contract is responsible by mint new MGD Nfts. Actually this contract is an ERC721.

MGDMarketplace.sol

This is an abstract smart contract that have the purchase function that will be used by its children (Set Price Market and Auction) and also a virtual list function that will be implemented in each way for each children. Here also there are some events and modifiers for general marketplace actions.

This is smart contract is composed by the MGDCompany and MGDnft. So this way is possible to do the required verification and actions based on these contracts.

MGDSetPrice.sol

This is a children of MGDMarketplace and have some specfic functionalities related with a set fixed price market. Some functions like:

MDGAuction.sol

This is also a children of MGDMarketplace. Here we have all the functionalities related with an auction like:

MGDMemoir.sol

A contract responsible by allow new address to create a memoir.

IMPORTANT!!

Deprecate code

The idea is stop to use the old smart contract created:

So now we have to do the required changes to adequate Backend + Frontend and the new Smart Contracts structure.

Tests

Also these PR is adding more 4 important files that contain the tests for the described smart contracts. Until now we have a total of 56 tests passing.

The files are:

Executing the tetst

To verify the tests. Go to this branch and run:

npx hardhat test

The results would be the followings:


MGDAuction.sol Smart Contract 
___________________________

This smart contract is responsible by all functionalities related with the marketplace auction. 

_________________________________ Tests related with listing a NFT for Auction _________________________________

         ARTIST BALANCE BEFORE LIST:  9999.99969
         ARTIST BALANCE AFTER LIST:  9999.99948
                So the gas estimation was more less: 0.53397141539906
      ✔ Should track newly listed item, transfer NFT from seller to MGD marketplace and emit the NftListed event. (74ms)
      ✔ Should revert the transaction if an artist is not the owner of the token and try to list on the gold dust marketplace.
      ✔ Should track a creation of an auction without a reserve price that expect the following conditions: 
         - Expect emit the AuctionCreated event; 
         - Expect auction structure attributes match with all passed to create auction function; 
         - Auction end time should not be started yet to 24 hours and should be zero. 
         - The auction price (initial price) should be zero. This way after any bid greater than zero the time of 24 hours should starts. (42ms)
      ✔ Should track a creation of an auction with a reserve price that expect the following conditions: 
         - Expect emit the AuctionCreated event; 
         - Expect auction structure attributes match with all passed to create auction function; 
         - Auction end time should not be started yet to 24 hours and should be zero. 
         - The auction price (initial price) should be zero. This way after any bid greater than zero the time of 24 hours should starts.

 ______________________________ PLACE A BID GENERAL UNHAPPY PATHS ______________________________
      ✔ Should revert with an AuctionEndedAlready() error when some user tries to bid in a timed auction that have ended already. (4092ms)
      ✔ Should revert with an AuctionCreatorCannotBid() error if the auction creator (NFT Owner) tries to place a bid. (44ms)
      ✔ Should revert with an LastBidderCannotBidAgain() error if the last bidder tries to place a bid again. (55ms)
      ✔ Should revert with an BidTooLow() error when some user tries to place bid with a value equal the highest bid. (56ms)
      ✔ Should revert with an BidTooLow() error when some user tries to place bid with a value less than the highest bid. (57ms)
      ✔ Should revert with an BidTooLow() error when some user tries to place the first bid with a value less than the reserve price in an auction with a reserve price.
      ✔ Should revert with an BidTooLow() error when some user tries to place the first bid with a value equal zero in an auction without a reserve price. (41ms)

 _________________________________ PLACE A BID HAPPY PATHS _________________________________

        ------------------ AUCTION WITH A RESERVE PRICE ------------------

                HIGHEST BID BEFORE FIRST BID:  BigNumber { value: "0" }
                AUCTION END TIME BEFORE BID:  BigNumber { value: "0" }
                GAS PRICE TO PLACE A BID:  BigNumber { value: "1000000028" }
                GAS LIMIT TO PLACE A BID:  BigNumber { value: "122439" }
                        TOTAL GAS ESTIMATION (USD):  0.0030609750857073

                AUCTION CONTRACT BALANCE BEFORE BID:  0
                AUCTION CONTRACT BALANCE AFTER BID:  4

                BIDDER BALANCE BEFORE BID:  9983.999358697965
                BIDDER BALANCE AFTER BID:  9979.999236258962
                BIDDER BALANCE AFTER + GAS + PRICE SHOULD BE EQUALS BALANCE BEFORE:  9983.999358697965

                AUCTION END TIME AFTER BID:  1681363421
                HIGHEST AFTER FIRST BID:  4
        ✔ Should place a first bid and: 
         - Verify if the highest bid was updated. 
         - Verify if the endAuction time was updated. 
         - Verify if the bidder balance was decreased the gas fee plus the auction price. 
         - Verify if the auction contract balance was added by the bid value. (209ms)

        ------------------ AUCTION WITHOUT A RESERVE PRICE ------------------

                HIGHEST BID BEFORE FIRST BID:  BigNumber { value: "0" }
                AUCTION END TIME BEFORE BID:  BigNumber { value: "0" }
                GAS PRICE TO PLACE A BID:  BigNumber { value: "1000000009" }
                GAS LIMIT TO PLACE A BID:  BigNumber { value: "142346" }
                        TOTAL GAS ESTIMATION (USD):  0.00355865003202785

                AUCTION CONTRACT BALANCE BEFORE BID:  0
                AUCTION CONTRACT BALANCE AFTER BID:  4

                BIDDER BALANCE BEFORE BID:  9979.999236258962
                BIDDER BALANCE AFTER BID:  9975.99909391296
                BIDDER BALANCE AFTER + GAS + PRICE SHOULD BE EQUALS BALANCE BEFORE:  9979.999236258962

                AUCTION END TIME AFTER BID:  1681363433
                HIGHEST AFTER FIRST BID:  4
        ✔ Should place a first bid and: 
         - Verify if the highest bid was updated. 
         - Verify if the endAuction time was updated. 
         - Verify if the bidder balance was decreased the gas fee plus the auction price. 
         - Verify if the auction contract balance was added by the bid value. (193ms)

        ------------------ SECOND BID BUT BEFORE THE LAST 5 MINUTES ------------------

                HIGHEST BID BEFORE FIRST BID:  BigNumber { value: "0" }
                AUCTION END TIME BEFORE BID:  BigNumber { value: "0" }

                HIGHEST BID AFTER FIRST BID:  4
                AUCTION END TIME AFTER FIRST BID:  1681363445

                AUCTION CONTRACT BALANCE BEFORE FIRST BID:  0
                AUCTION CONTRACT BALANCE AFTER FIRST BID:  4
                AUCTION CONTRACT BALANCE AFTER SECOND BID:  6

                BIDDER 1 BALANCE BEFORE FIRST BID:  9975.99909391296
                BIDDER 1 BALANCE AFTER FIRST BID:  9971.998951566959
                BIDDER 1 BALANCE AFTER + GAS + PRICE SHOULD BE EQUALS BALANCE BEFORE:  9975.99909391296
                BIDDER 1 BALANCE AFTER SECOND BID SHOULD BE REFUNDED:  9975.998951566959

                BIDDER 2 BALANCE BEFORE FIRST BID:  9999.999875339932
                BIDDER 2 BALANCE AFTER FIRST BID:  9993.999800386933
                BIDDER 2 BALANCE AFTER + GAS + PRICE SHOULD BE EQUALS BALANCE BEFORE:  9999.999875339932
                HIGHEST AFTER SECOND BID:  6

                AUCTION END TIME AFTER SECOND BID SHOULD KEEP THE SAME:  1681363445
        ✔ Should place a first bid and: 
         - Verify if the highest bid was updated. 
         - Verify if the endAuction time was updated. 
         - Verify if the bidder balance was decreased the gas fee plus the auction price. 
         - Verify if the auction contract balance was added by the bid value. (342ms)

        ------------------ SECOND BID NOW IN THE LAST 5 MINUTES ------------------

                AUCTION END TIME BEFORE FIRST BID:  0
                AUCTION END TIME AFTER FIRST BID:  1681363458

                Waiting until the last 5 minutes of the auction...

                AUCTION END TIME AFTER SECOND BID SHOULD BE INCREASED (In our test, we're using 8 seconds for the last time like example, 10 second for auction duration and 3000 seconds of timeout between the two bids):  1681363466
        ✔ Should place a second bid in the last 5 minutes and: 
         - Verify if the end time was increased by more 5 minutes. (3170ms)

 _________________________________ END AUCTION UNHAPPY PATHS _________________________________

      ✔ Should revert with MGDMarketplaceItemIsNotListed error if the end auction function is called and the tokenId was not listed on MGDAuction.
      ✔ Should revert with AuctionTimeNotStartedYet error if the end auction function is called and the auction have not received any bids yet.
      ✔ Should revert with AuctionCannotBeEndedYet error if the end auction function is called before the time of duration of the auction be ended. (51ms)
      ✔ Should revert with MGDMarketFunctionForSetPriceListedNFT error if the purchaseNFT function with one parameter is called to buy an item that is listed to Auction. For that the purchseNFT function with two params must be called and its function is internal and just can be called by the childrens smart contracts like the MGDAuction.

 _________________________________ END AUCTION FOR PRIMARY SALE _________________________________

         GAS PRICE END AUCTION:  BigNumber { value: "1000000008" }
         GAS LIMIT END AUCTION:  BigNumber { value: "149551" }
                 TOTAL GAS ESTIMATION END AUCTION (USD):  0.0037387750299102004

                 AUCTION HIGHEST BID:  20
                 Primary Market fee:  3
                 Collector fee:  0.6
                 Marketplace owner fee:  3.6
                 Balance to seller:  16.4

                 MARKETPLACE OWNER BALANCE BEFORE SALE:  9999.894533028086
                 (OBS: IT'S A LITTLE BIT LESS THAN IT SHOULD BE BECAUSE THE EXECUTION OF ENDAUCTION FUNCTION + PURCHASENFT FUNCTION GAS) 
                 MARKETPLACE OWNER BALANCE AFTER SALE:  10003.494389098083
                 MARKETPLACE OWNER BALANCE AFTER SALE SHOULD BE:  10003.494533028084
                 SELLER BALANCE BEFORE SALE:  9999.992448900028
                 SELLER BALANCE AFTER SALE:  10016.392448900027
                 AUCTION WINNER BALANCE BEFORE SALE:  9971.998655387957
                 AUCTION WINNER BALANCE AFTER SALE:  9951.998532948955
      ✔ Should:
         - Simulate a primary sale that transfer an NFT to the buyer;
         - Verify if the item changed status for sale;
         - Verify if the seller balance increases;
         - Verify if the marketplace's owner receives the fee;
         - Verify if the isSecondarySale attribute was set to true;
         - Verify if the buyer balance was deacresed exactly the gas fee + the token price; (3465ms)
    ------------------ END AUCTION NFT FOR SECONDARY MARKET ------------------
         GAS PRICE:  BigNumber { value: "1000000008" }
         GAS LIMIT:  BigNumber { value: "139579" }
                 TOTAL GAS ESTIMATION (USD):  0.0034894750279157996

                 ITEM PRICE:  20
                 Secondary Market fee:  1
                 Royalty fee:  1
                 Balance to seller:  18

                 MARKETPLACE OWNER BALANCE BEFORE AUCTION:  10006.909221026042
                 MARKETPLACE OWNER BALANCE AFTER AUCTION:  10007.909087197042
                 SELLER BALANCE BEFORE AUCTION:  9932.998305462954
                 SELLER BALANCE AFTER AUCTION:  9950.998305462954
                 ARTIST BALANCE BEFORE AUCTION:  10031.972088097024
                 ARTIST BALANCE AFTER AUCTION WITH THE ROYALTY:  10032.972088097024
                 AUCTION WINNER BALANCE BEFORE AUCTION:  9987.999720052932
                 AUCTION WINNER BALANCE AFTER AUCTION:  9967.99959761393
      ✔ Should simulate a secondary sale that transfer an NFT to the buyer, verify if the item changed status for sale, verify if the seller balance increases and also if the marketplace's owner receives the fee and verify if the artist creator have received the royalty. (6581ms)

MGDCompany.sol Smart Contract 
_________________________________________

This smart contract is responsible by the functionalities related with MGD Management.

--------------- Tests related with the set validator functionality ---------------

         GAS PRICE:  BigNumber { value: "1000000008" }
         GAS LIMIT:  BigNumber { value: "47791" }
                 TOTAL GAS ESTIMATION (USD):  0.0011947750095582
      ✔ Should set a new validator if is the owner and this new validator should can whitelist or blacklist an artist. (78ms)
      ✔ Should revert with a MGDCompanyUnauthorized error if an address that is not the owner try to set a new validator.

--------------- Tests related with whitelist/blacklist artist ---------------

         GAS PRICE:  BigNumber { value: "1000000008" }
         GAS LIMIT:  BigNumber { value: "47929" }
                 TOTAL GAS ESTIMATION (USD):  0.0011982250095858
      ✔ Should whitelist an after blacklist artist. (100ms)
      ✔ Should revert with a MGDCompanyUnauthorized error if an address that is not the owner try to whitelist or blacklist an artist.

--------------- Tests related with the update primary sale fee functionality ---------------

         GAS PRICE:  BigNumber { value: "1000000008" }
         GAS LIMIT:  BigNumber { value: "28707" }
                 TOTAL GAS ESTIMATION (USD):  0.0007176750057414
      ✔ Should update the fee if is the owner. (43ms)
      ✔ Should revert with a MGDCompanyUnauthorized error if an address that is not the owner try to update the primary sale fee.

--------------- Tests related with the update secondary sale fee functionality ---------------

         GAS PRICE:  BigNumber { value: "1000000008" }
         GAS LIMIT:  BigNumber { value: "28672" }
                 TOTAL GAS ESTIMATION (USD):  0.0007168000057344
      ✔ Should update the secondary fee if is the owner. (44ms)
      ✔ Should revert with a MGDCompanyUnauthorized error if an address that is not the owner try to update the secondary sale fee.

--------------- Tests related with the update collector fee functionality ---------------

         GAS PRICE:  BigNumber { value: "1000000008" }
         GAS LIMIT:  BigNumber { value: "28652" }
                 TOTAL GAS ESTIMATION (USD):  0.0007163000057304
      ✔ Should update the collector fee if is the owner. (47ms)
      ✔ Should revert with a MGDCompanyUnauthorized error if an address that is not the owner try to update the collector fee.

--------------- Tests related with the update max royalty fee functionality ---------------

         GAS PRICE:  BigNumber { value: "1000000008" }
         GAS LIMIT:  BigNumber { value: "28707" }
                 TOTAL GAS ESTIMATION (USD):  0.0007176750057414
      ✔ Should update the max_royalty_fee if is the owner. (60ms)
      ✔ Should revert with a MGDCompanyUnauthorized error if an address that is not the owner try to update the max royalty fee.
      ✔ Should be possible to mint a NFT with a new maximum royalty set. (51ms)
      ✔ Should revert with a MGDnftRoyaltyInvalidPercentage error if some artist try to mint with a royalty percent greater than new max royalty that is 25. (56ms)

--------------- Tests related with the update auction duration functionality ---------------

         GAS PRICE:  BigNumber { value: "1000000008" }
         GAS LIMIT:  BigNumber { value: "28657" }
                 TOTAL GAS ESTIMATION (USD):  0.0007164250057314
      ✔ Should update the auction duration if is the owner. (47ms)
      ✔ Should revert with a MGDCompanyUnauthorized error if an address that is not the owner try to update the auction duration time.

--------------- Tests related with the update auction final time functionality ---------------

         GAS PRICE:  BigNumber { value: "1000000008" }
         GAS LIMIT:  BigNumber { value: "28591" }
                 TOTAL GAS ESTIMATION (USD):  0.0007147750057182001
      ✔ Should update the auction final time duration if is the owner. (41ms)
      ✔ Should revert with a MGDCompanyUnauthorized error if an address that is not the owner try to update the auction final time. duration. (39ms)

MGDSetPrice.sol Smart Contract 
___________________________________________________

This smart contract is responsible by all functionalities related with the fixed price market. 

--------------- Tests related witn the list NFT functionality ---------------

         ARTIST BALANCE BEFORE LIST:  10032.97143
         ARTIST BALANCE AFTER LIST:  10032.97129
                So the gas estimation was more less: 0.35549250284394
      ✔ Should track newly listed item, transfer NFT from seller to MGD marketplace and emit the NftListed event. (41ms)
      ✔ Should revert the transaction if an artist tries to list its nft with price less than or equal zero.
      ✔ Should revert the transaction if an artist is not the owner of the token and try to list on the gold dust marketplace.

--------------- Tests related with the update a listed NFT functionality ---------------

         GAS PRICE:  BigNumber { value: "1000000008" }
         GAS LIMIT:  BigNumber { value: "85309" }
                 TOTAL GAS ESTIMATION (USD):  0.0021327250170618
      ✔ Should track if a listed item was correctly updated and emit the NftListedItemUpdated event. We should remember that in this moment the owner of the NFT is the marketplace. (275ms)
      ✔ Should revert the transaction with InvalidInput error if the marketplace owner tries to update some listed nft with price less than or equal zero.
      ✔ Should revert the transaction with an GDNFTMarketplace__Unauthorized error if some address that is not the seller try to update the NFT listed.
      ✔ Should revert the transaction with an MGDMarketplaceItemIsNotListed error if some user tries to update an item that is not on sale.

--------------- Tests related with delist NFT functionality ---------------
         GAS PRICE:  BigNumber { value: "1000000008" }
         GAS LIMIT:  BigNumber { value: "98027" }
                 TOTAL GAS ESTIMATION (USD):  0.0024506750196054
      ✔ Should delist a NFT from the marketplace and emit the NFTRemovedFromMarketplace event. (183ms)
      ✔ Should revert with a GDNFTMarketplace__Unauthorized error if some address that is not the item seller try to delist its NFT from marketplace.

--------------- Purchase NFT on primary market ---------------

         GAS PRICE:  BigNumber { value: "1000000008" }
         GAS LIMIT:  BigNumber { value: "156476" }
                 TOTAL GAS ESTIMATION (USD):  0.003911900031295199

                 ITEM PRICE:  20
                 Primary Market fee:  3
                 Collector fee:  0.6
                 Marketplace owner fee:  3.6
                 Balance to seller:  16.4

                 MARKETPLACE OWNER BALANCE BEFORE SALE:  10008.01636309146
                 MARKETPLACE OWNER BALANCE AFTER SALE:  10011.61636309146
                 SELLER BALANCE BEFORE SALE:  10033.788104594993
                 SELLER BALANCE AFTER SALE:  10050.188104594992
                 BUYER BALANCE BEFORE SALE:  9949.998022936952
                 BUYER BALANCE AFTER SALE:  9929.997869842951
      ✔ Should:
         - Simulate a primary sale that transfer an NFT to the buyer;
         - Verify if the item changed status for sale;
         - Verify if the seller balance increases;
         - Verify if the marketplace's owner receives the fee;
         - Verify if the isSecondarySale attribute was set to true;
         - Verify if the buyer balance was deacresed exactly the gas fee + the token price; (362ms)
      ✔ Should revert with MGDMarketplaceItemIsNotListed error if the user tries to buy a NFT that was already sold.
      ✔ Should revert with MGDMarketplaceIncorrectAmountSent if the user tries to buy an itemId with an amount greater than the item's price.
      ✔ Should revert with MGDMarketplaceIncorrectAmountSent if the user tries to buy an itemId with an amount less than the item's price.

--------------- Purchase NFT on secondary market ---------------

         GAS PRICE:  BigNumber { value: "1000000008" }
         GAS LIMIT:  BigNumber { value: "129189" }
                 TOTAL GAS ESTIMATION (USD):  0.0032297250258378

                 ITEM PRICE:  20
                 Secondary Market fee:  1
                 Royalty fee:  1
                 Balance to seller:  18

                 MARKETPLACE OWNER BALANCE BEFORE SALE:  10018.80250148335
                 MARKETPLACE OWNER BALANCE AFTER SALE:  10019.80250148335
                 SELLER BALANCE BEFORE SALE:  9889.997475545948
                 SELLER BALANCE AFTER SALE:  9907.997475545948
                 ARTIST BALANCE BEFORE:  10082.986661922982
                 ARTIST BALANCE AFTER ROYALTY:  10083.986661922982
                 BUYER BALANCE BEFORE SALE:  9967.99950079093
                 BUYER BALANCE AFTER SALE:  9947.999374885929
      ✔ Should simulate a secondary sale that transfer an NFT to the buyer, verify if the item changed status for sale, verify if the seller balance increases and also if the marketplace's owner receives the fee and verify if the artist creator have received the royalty. (382ms)

MGDnft.sol Smart Contract 
______________________________________________

This smart contract is responsible by mint new MGD Nfts. Actually this contract is an ERC721. 

--------------- Test related with the mint NFT functionality ---------------

         ARTIST BALANCE BEFORE MINT:  10083.98666
         ARTIST BALANCE AFTER MINT:  10083.98649
                So the gas estimation was more less: 0.43046500344372
      ✔ Should track each minted NFT. This is verifying if: 
         - The tokenURI was set correctly. 
         - The tokenId was bound with the artist for future royalties payments. 
         - The artist is the owner of the token. 
         - The royalty percentage was set correctly. 
         - The balanceOf the artists that mint an NFT was increased. (500ms)
      ✔ Should revert with a MGDnftRoyaltyInvalidPercentage error if some artist try to mint with a royalty percent greater than 20.
      ✔ Should revert with a MGDnftUnauthorized error if some not whitelisted artist try to mint a NFT.

  56 passing (36s)