├── .env.example ├── .gitignore ├── README.md ├── contracts ├── PodShip.sol ├── PodShipAuction.sol └── PodShipErrors.sol ├── hardhat.config.js ├── package-lock.json ├── package.json ├── scripts ├── deploy-FVM.js └── deploy.js ├── test └── podship-auction-test.js └── yarn.lock /.env.example: -------------------------------------------------------------------------------- 1 | POLYGON_TESTNET_URL= 2 | FILECOIN_TESTNET_URL= 3 | PRIVATE_KEY= 4 | ETHERSCAN_API_KEY= -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | /node_modules 3 | .env 4 | coverage 5 | coverage.json 6 | typechain 7 | typechain-types 8 | 9 | #Hardhat files 10 | cache 11 | artifacts 12 | 13 | coverage.json 14 | 15 | yarn-error.log -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | - Filecoin Testnet: https://hyperspace.filfox.info/en/address/0xcc4E8Ce3fAc29a6d816AF7CFE396781A91CdD3c5 2 | - Polygon Testnet: https://mumbai.polygonscan.com/address/0x981B5Ad183DE724a1593dd0237f45F51B5bfab97#code -------------------------------------------------------------------------------- /contracts/PodShip.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.9; 3 | 4 | import "hardhat/console.sol"; 5 | import "./PodShipErrors.sol"; 6 | import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; 7 | import {Counters} from "@openzeppelin/contracts/utils/Counters.sol"; 8 | import {ERC721URIStorage} from "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; 9 | 10 | ///// @title PodShip Podcast NFT 11 | ///// @author ABDul Rehman 12 | ///// @notice PodShip's main contract 13 | contract PodShip is ERC721URIStorage, Ownable { 14 | using Counters for Counters.Counter; 15 | Counters.Counter private _tokenId; 16 | Counters.Counter private _podcastId; 17 | 18 | struct PodcastNFT { 19 | address nftCreator; 20 | address nftOwner; 21 | uint256 tokenId; 22 | } 23 | 24 | event PodShipContractDeployed(); 25 | event ProdcastCreated( 26 | string indexed IPFSUri, 27 | address indexed nftCreator, 28 | uint256 indexed tokenId 29 | ); 30 | event Tipping( 31 | uint256 indexed podcastId, 32 | uint256 indexed tip, 33 | address indexed supporter 34 | ); 35 | 36 | uint256 public constant MINIMUM_TIP = 1 * 10**18; 37 | mapping(uint256 => PodcastNFT) public podcastId; 38 | 39 | constructor() ERC721("PodShip Podcast NFT", "PODSHIP") { 40 | emit PodShipContractDeployed(); 41 | } 42 | 43 | 44 | function mintNFT(string memory ipfsURI) external returns(uint256) { 45 | _tokenId.increment(); 46 | _podcastId.increment(); 47 | uint256 token_Id = _tokenId.current(); 48 | podcastId[_podcastId.current()] = PodcastNFT( 49 | msg.sender, 50 | msg.sender, 51 | token_Id 52 | ); 53 | _safeMint(msg.sender, token_Id); 54 | _setTokenURI(token_Id, ipfsURI); 55 | 56 | emit ProdcastCreated(ipfsURI, msg.sender, token_Id); 57 | return token_Id; 58 | } 59 | 60 | function tipCreator(uint256 _podcastID) external payable { 61 | require(podcastId[_podcastID].nftCreator != 0, "Wrong/Non-Existent PodcastID"); 62 | if(msg.value < MINIMUM_TIP){ revert PodShip__TippingLessThanOneMaticNotAllowed(); } 63 | (bool sent, ) = (podcastId[_podcastID].nftCreator).call{value: msg.value}(""); 64 | if(!sent){ revert PodShip__FailedToSendMATIC(); } 65 | 66 | emit Tipping(_podcastID, msg.value, msg.sender); 67 | } 68 | 69 | function getNftCreator(uint256 _podcastID) public view returns(address) { 70 | return podcastId[_podcastID].nftCreator; 71 | } 72 | 73 | function getNftOwner(uint256 _podcastID) public view returns(address) { 74 | return podcastId[_podcastID].nftOwner; 75 | } 76 | 77 | function getNftTokenId(uint256 _podcastID) public view returns(uint256) { 78 | return podcastId[_podcastID].tokenId; 79 | } 80 | 81 | function getCurrentToken() public view returns (uint256) { 82 | return _tokenId.current(); 83 | } 84 | 85 | } -------------------------------------------------------------------------------- /contracts/PodShipAuction.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.9; 3 | 4 | import "./PodShipErrors.sol"; 5 | import "hardhat/console.sol"; 6 | import {PodShip} from "./PodShip.sol"; 7 | import {ERC2981} from "@openzeppelin/contracts/token/common/ERC2981.sol"; 8 | import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; 9 | 10 | ///// @notice PodShip's Auctions core contract 11 | contract PodShipAuction is Ownable, PodShip, ERC2981, ReentrancyGuard { 12 | using Counters for Counters.Counter; 13 | Counters.Counter private auctionId; 14 | 15 | event AuctionCreated( 16 | uint256 indexed auctionId, 17 | uint256 indexed reservePrice, 18 | uint96 indexed royaltyPercent, 19 | uint256 podcastId, 20 | uint256 duration 21 | ); 22 | event BidPlaced( 23 | uint256 indexed auctionId, 24 | address indexed bidder, 25 | uint256 indexed bid 26 | ); 27 | event AuctionResulted( 28 | uint256 indexed auctionId, 29 | address indexed winner, 30 | uint256 winningBid 31 | ); 32 | event AuctionCancelled( 33 | uint256 indexed auctionId 34 | ); 35 | event PlatformFeeChanged( 36 | uint256 indexed platformFee 37 | ); 38 | event PlatformFeeRecipientChanged( 39 | address indexed platformFeeRecipient 40 | ); 41 | event BidRefunded( 42 | uint256 indexed auctionId, 43 | address indexed bidder, 44 | uint256 bid 45 | ); 46 | event RequestedWinner(uint256 indexed requestId); 47 | event RecentWinner(address indexed recentWinner); 48 | 49 | uint256 private platformFee; 50 | uint256 public constant MAX_PLATFORM_FEE = 10; 51 | address private platformFeeRecipient; 52 | 53 | constructor(uint256 _platformFee, address _platformFeeRecipient){ 54 | require(_platformFee <= MAX_PLATFORM_FEE); 55 | platformFee = _platformFee; 56 | platformFeeRecipient = _platformFeeRecipient; 57 | } 58 | 59 | struct Auction { 60 | uint256 podcastId; 61 | uint256 reservePrice; 62 | uint256 startTime; 63 | uint256 endTime; 64 | uint256 duration; 65 | uint96 royaltyPercent; 66 | bool listed; 67 | } 68 | 69 | struct Bidding { 70 | address highestBidder; 71 | uint256 highestBid; 72 | } 73 | 74 | mapping(uint256 => Auction) public auctions; 75 | mapping(uint256 => Bidding) public bidders; 76 | 77 | /// @dev mapinng msgSender -> msgValue -> auctionId 78 | mapping(address => mapping(uint => uint)) public bids; 79 | 80 | /// @dev Only NFT Owner can start the auction, Auction Duration days can be 1 to 7 days long, Royalty Percent can on be between 1 & 50 and reserve prive should be more than 1 MATIC. 81 | /// @param _reservePrice - Auction starting price for the NFT 82 | /// @param _duration - Duration of the Auction in days 83 | /// @param _royaltyPercent - Royalty Percentage NFT creator will get on the resales 84 | function startAuction(uint256 _podcastId, uint256 _reservePrice, uint256 _duration, uint96 _royaltyPercent) public returns(uint256) { 85 | if(msg.sender != ownerOf(_podcastId)){ revert PodShipAuction__OnlyNftOwnerCanStartTheAuction(); } 86 | if(_duration < 1){ revert PodShipAuction__AuctionDuration_1to7_DaysAllowed(); } 87 | if(_duration > 7){ revert PodShipAuction__AuctionDuration_1to7_DaysAllowed(); } 88 | if(_royaltyPercent < 1){ revert PodShipAuction__NftRoyalties_1to50_PercentAllowed(); } 89 | if(_royaltyPercent > 50){ revert PodShipAuction__NftRoyalties_1to50_PercentAllowed(); } 90 | if(_reservePrice < 1){ revert PodShipAuction__ReservePriceZeroNotAllowed(); } 91 | auctionId.increment(); 92 | approve(address(this), podcastId[_podcastId].tokenId); 93 | // uint256 auction_duration = _duration * 86400; ///// For Mainnet 94 | uint256 auction_duration = _duration * 60; ///// For testnet/testing 95 | _setTokenRoyalty(podcastId[_podcastId].tokenId, podcastId[_podcastId].nftCreator, _royaltyPercent); 96 | auctions[auctionId.current()] = Auction(_podcastId, _reservePrice * 10**18, 0, 0, auction_duration, _royaltyPercent, true); 97 | 98 | emit AuctionCreated(auctionId.current(), _reservePrice * 10**18, _royaltyPercent, _podcastId, auction_duration); 99 | return auctionId.current(); 100 | } 101 | 102 | function bid(uint256 _auctionId) public payable { 103 | if(msg.sender == podcastId[auctions[_auctionId].podcastId].nftOwner){ revert PodShipAuction__NftOwnerCannotBid(); } 104 | if(!auctions[_auctionId].listed){ revert PodShipAuction__NftNotOnAuction(); } 105 | if(bidders[_auctionId].highestBidder == address(0)) { 106 | auctions[_auctionId].startTime = block.timestamp; 107 | } 108 | auctions[_auctionId].endTime = auctions[_auctionId].startTime + auctions[_auctionId].duration; 109 | if(block.timestamp > auctions[_auctionId].endTime){ revert PodShipAuction__AuctionEnded(); } 110 | if(msg.value == 0) { revert PodShipAuction__InputAmountCannotBeZero(); } 111 | if(msg.value < auctions[_auctionId].reservePrice){ 112 | revert PodShipAuction__InputAmountBelowNftReservePrice(); 113 | } 114 | if(msg.value <= bidders[_auctionId].highestBid){ 115 | revert PodShipAuction__InputAmountBelowNftLastHighestBid(); 116 | } 117 | if (msg.sender != address(0)) { 118 | bids[msg.sender][_auctionId] += msg.value; 119 | } 120 | bidders[_auctionId].highestBidder = msg.sender; 121 | bidders[_auctionId].highestBid = msg.value; 122 | 123 | emit BidPlaced(_auctionId, msg.sender, msg.value); 124 | } 125 | 126 | function endAuction(uint256 _auctionId) public nonReentrant { 127 | if(!auctions[_auctionId].listed){ revert PodShipAuction__NftNotOnAuction(); } 128 | if(msg.sender != podcastId[auctions[_auctionId].podcastId].nftOwner){ revert PodShipAuction__OnlyNftOwnerAllowed(); } 129 | if(block.timestamp < auctions[_auctionId].endTime) { revert PodShipAuction__AuctionInProgress(); } 130 | auctions[_auctionId].listed = false; 131 | safeTransferFrom(podcastId[auctions[_auctionId].podcastId].nftOwner, bidders[_auctionId].highestBidder, podcastId[auctions[_auctionId].podcastId].tokenId); 132 | uint256 platformCut = (platformFee * bidders[_auctionId].highestBid)/100; 133 | uint256 NftOwnerCut = bidders[_auctionId].highestBid - platformCut; 134 | (bool pass, ) = payable(platformFeeRecipient).call{value: platformCut}(""); 135 | if(!pass){ revert PodShipAuction__platformFeeTransferFailed(); } 136 | (bool success, ) = payable(podcastId[auctions[_auctionId].podcastId].nftOwner).call{value: NftOwnerCut}(""); 137 | if(!success){ revert PodShipAuction__NftOwnerCutTransferFailed(); } 138 | podcastId[auctions[_auctionId].podcastId].nftOwner = bidders[_auctionId].highestBidder; 139 | 140 | emit AuctionResulted(_auctionId, bidders[_auctionId].highestBidder, bidders[_auctionId].highestBid); 141 | bidders[_auctionId].highestBid = 0; 142 | auctions[_auctionId].endTime = 0; 143 | } 144 | 145 | function cancelAuction(uint256 _auctionId) public { 146 | if(msg.sender != podcastId[auctions[_auctionId].podcastId].nftOwner){ revert PodShipAuction__OnlyAuctionCreatorAllowed(); } 147 | if(msg.sender != podcastId[auctions[_auctionId].podcastId].nftCreator){ revert PodShipAuction__OnlyAuctionCreatorAllowed(); } 148 | delete auctions[_auctionId]; 149 | 150 | emit AuctionCancelled(_auctionId); 151 | } 152 | 153 | function refundBid(uint256 _auctionId) public nonReentrant { 154 | if(msg.sender == bidders[_auctionId].highestBidder){ revert PodShipAuction__AuctonWinnerCannotWithdraw();} 155 | if(bids[msg.sender][_auctionId] == 0){ revert PodShipAuction__UserDidNotParticipatedInTheAuction(); } 156 | uint256 refundAmount = bids[msg.sender][_auctionId]; 157 | bids[msg.sender][_auctionId] = 0; 158 | (bool sent, ) = payable(msg.sender).call{value: refundAmount}(""); 159 | if(!sent){ revert PodShipAuction__WithdrawFailed(); } 160 | emit BidRefunded(_auctionId, msg.sender, refundAmount); 161 | } 162 | 163 | function withdraw() external onlyOwner { 164 | (bool withdrawn, ) = payable(owner()).call{value: address(this).balance}(""); 165 | if(!withdrawn){revert PodShipAuction__WithdrawFailed(); } 166 | } 167 | 168 | function changePlatformFee(uint256 _platformFee) external onlyOwner { 169 | require(_platformFee <= MAX_PLATFORM_FEE); 170 | platformFee = _platformFee; 171 | emit PlatformFeeChanged(_platformFee); 172 | } 173 | 174 | function changePlatformFeeRecipient(address _platformFeeRecipient) external onlyOwner { 175 | platformFeeRecipient = _platformFeeRecipient; 176 | emit PlatformFeeRecipientChanged(_platformFeeRecipient); 177 | } 178 | 179 | function getPlatformFee() public view returns(uint256) { 180 | return platformFee; 181 | } 182 | function getPlatformFeeRecipient() public view returns(address) { 183 | return platformFeeRecipient; 184 | } 185 | 186 | function supportsInterface(bytes4 interfaceId) public view virtual override(ERC2981, ERC721) returns (bool) { 187 | return super.supportsInterface(interfaceId); 188 | } 189 | } -------------------------------------------------------------------------------- /contracts/PodShipErrors.sol: -------------------------------------------------------------------------------- 1 | /// SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.9; 3 | 4 | // PodShip.sol: 5 | error PodShip__ZeroAddress(); 6 | error PodShip__TippingLessThanOneMaticNotAllowed(); 7 | error PodShip__FailedToSendMATIC(); 8 | 9 | // PodShipAuction.sol: 10 | error PodShipAuction__NftOwnerCannotBid(); 11 | error PodShipAuction__InputAmountCannotBeZero(); 12 | error PodShipAuction__OnlyNftOwnerCanStartTheAuction(); 13 | error PodShipAuction__AuctionDuration_1to7_DaysAllowed(); 14 | error PodShipAuction__NftRoyalties_1to50_PercentAllowed(); 15 | error PodShipAuction__ReservePriceZeroNotAllowed(); 16 | error PodShipAuction__NftNotOnAuction(); 17 | error PodShipAuction__AuctionEnded(); 18 | error PodShipAuction__OnlyNftOwnerAllowed(); 19 | error PodShipAuction__AuctionInProgress(); 20 | error PodShipAuction__InputAmountBelowNftReservePrice(); 21 | error PodShipAuction__InputAmountBelowNftLastHighestBid(); 22 | error PodShipAuction__platformFeeTransferFailed(); 23 | error PodShipAuction__NftOwnerCutTransferFailed(); 24 | error PodShipAuction__AuctonWinnerCannotWithdraw(); 25 | error PodShipAuction__UserDidNotParticipatedInTheAuction(); 26 | error PodShipAuction__WithdrawFailed(); 27 | error PodShipAuction__OnlyAuctionCreatorAllowed(); 28 | error UpkeepNotNeeded(uint256 tippersLength, uint256 currentTime); -------------------------------------------------------------------------------- /hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomicfoundation/hardhat-toolbox"); 2 | require("dotenv").config({ path: ".env" }); 3 | 4 | PRIVATE_KEY = process.env.PRIVATE_KEY; 5 | ETHERSCAN_API_KEY = process.env.ETHERSCAN_API_KEY; 6 | POLYGON_TESTNET_URL = process.env.POLYGON_TESTNET_URL; 7 | FILECOIN_TESTNET_URL = process.env.FILECOIN_TESTNET_URL; 8 | 9 | module.exports = { 10 | solidity: { 11 | version: "0.8.9", 12 | settings: { 13 | optimizer: { 14 | enabled: true, 15 | runs: 200, 16 | }, 17 | }, 18 | }, 19 | networks: { 20 | matic: { 21 | url: POLYGON_TESTNET_URL, 22 | accounts: [PRIVATE_KEY], 23 | gas: 2100000, 24 | gasPrice: 8000000000 25 | }, 26 | hyperspace: { 27 | chainId: 3141, 28 | url: FILECOIN_TESTNET_URL, 29 | accounts: [PRIVATE_KEY], 30 | }, 31 | localhost: { 32 | url: "http://127.0.0.1:8545/", 33 | chainId: 31337, 34 | } 35 | }, 36 | etherscan: { 37 | apiKey: ETHERSCAN_API_KEY 38 | } 39 | }; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "license": "MIT", 3 | "devDependencies": { 4 | "@nomicfoundation/hardhat-network-helpers": "^1.0.0", 5 | "@nomicfoundation/hardhat-toolbox": "^2.0.0", 6 | "@nomiclabs/hardhat-etherscan": "^3.0.0", 7 | "@typechain/ethers-v5": "^10.1.0", 8 | "@typechain/hardhat": "^6.1.2", 9 | "@types/mocha": "^9.1.0", 10 | "hardhat": "^2.12.0", 11 | "hardhat-gas-reporter": "^1.0.9", 12 | "solidity-coverage": "^0.8.1", 13 | "ts-node": ">=8.0.0", 14 | "typechain": "^8.1.0", 15 | "typescript": ">=4.5.0" 16 | }, 17 | "dependencies": { 18 | "@chainlink/contracts": "^0.5.1", 19 | "@glif/filecoin-address": "^2.0.20", 20 | "@nomicfoundation/hardhat-chai-matchers": "^1.0.3", 21 | "@nomicfoundation/hardhat-toolbox": "^2.0.0", 22 | "@nomiclabs/hardhat-ethers": "^2.1.1", 23 | "@openzeppelin/contracts": "^4.7.3", 24 | "chai": "^4.3.6", 25 | "dotenv": "^16.0.3", 26 | "ethers": "^5.7.1", 27 | "hardhat": "^2.11.2", 28 | "hardhat-deploy": "^0.11.22", 29 | "hardhat-deploy-ethers": "^0.3.0-beta.13", 30 | "request": "^2.88.2", 31 | "util": "^0.12.5" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /scripts/deploy-FVM.js: -------------------------------------------------------------------------------- 1 | const {ethers} = require("hardhat"); 2 | require("dotenv").config({ path: ".env" }); 3 | 4 | PRIVATE_KEY = process.env.PRIVATE_KEY; 5 | const wallet = new ethers.Wallet(PRIVATE_KEY, ethers.provider) 6 | 7 | async function main() { 8 | console.log("Wallet Ethereum Address:", wallet.address) 9 | const PodShipContract = await ethers.getContractFactory("PodShipAuction", wallet); 10 | const deployedPodShip = await PodShipContract.deploy(5, "0x66d126586d17e27A3E57A2C0301ebc0cCA2c45C7"); 11 | await deployedPodShip.deployed(); 12 | console.log(`PodShip Contract Address: ${deployedPodShip.address}`); 13 | } 14 | 15 | main() 16 | .then(() => process.exit(0)) 17 | .catch((error) => { 18 | console.error(error); 19 | process.exit(1); 20 | }); -------------------------------------------------------------------------------- /scripts/deploy.js: -------------------------------------------------------------------------------- 1 | const {ethers} = require("hardhat"); 2 | 3 | async function main() { 4 | const PodShipContract = await ethers.getContractFactory("PodShipAuction"); 5 | const deployedPodShip = await PodShipContract.deploy(5, "0x66d126586d17e27A3E57A2C0301ebc0cCA2c45C7"); 6 | await deployedPodShip.deployed(); 7 | console.log(`PodShip Contract Address: ${deployedPodShip.address}`); 8 | 9 | console.log("Waiting for block confirmations & Verifying.....") 10 | await deployedPodShip.deployTransaction.wait(5) 11 | await verify(deployedPodShip.address, [5, "0x66d126586d17e27A3E57A2C0301ebc0cCA2c45C7"]) 12 | } 13 | 14 | const verify = async (contractAddress, args) => { 15 | console.log("Verifying contract.....") 16 | try { 17 | await run("verify:verify", { 18 | address: contractAddress, 19 | constructorArguments: args, 20 | }) 21 | } catch (e) { 22 | if (e.message.toLowerCase().includes("already verified")) { 23 | console.log("Already Verified!") 24 | } else { 25 | console.log(e) 26 | } 27 | } 28 | } 29 | 30 | main() 31 | .then(() => process.exit(0)) 32 | .catch((error) => { 33 | console.error(error); 34 | process.exit(1); 35 | }); -------------------------------------------------------------------------------- /test/podship-auction-test.js: -------------------------------------------------------------------------------- 1 | const { assert } = require("chai"); 2 | const { ethers } = require("hardhat"); 3 | 4 | describe("PodshipAuction", async function () { 5 | let PodShipContractFactory, deployedPodShip, PodShipNFTContractFactory, deployedPodShipNFT; 6 | beforeEach(async function () { 7 | // Auction smart contract deployment 8 | PodShipContractFactory = await ethers.getContractFactory("PodShipAuction"); 9 | deployedPodShip = await PodShipContractFactory.deploy(5, "0x66d126586d17e27A3E57A2C0301ebc0cCA2c45C7", "0xb74BcaBBbE5BC2De2540F34B0BB2549f62893A8d", "0x7a1BaC17Ccc5b313516C5E16fb24f7659aA5ebed", "0x4b09e658ed251bcafeebbc69400383d49f344ace09b9576fe248bb02c003fe9f", "2368", "2500000"); 10 | await deployedPodShip.deployed(); 11 | 12 | // NFT smart contract deployment 13 | PodShipNFTContractFactory = await ethers.getContractFactory("PodShip"); 14 | deployedPodShipNFT = await PodShipNFTContractFactory.deploy("0x66d126586d17e27A3E57A2C0301ebc0cCA2c45C7"); 15 | await deployedPodShipNFT.deployed(); 16 | console.log(`PodShipNFT Contract Address: ${deployedPodShipNFT.address}`); 17 | 18 | 19 | }) 20 | 21 | it("it should mint a supporters NFT successfully to owners address", async function () { 22 | let targetOwnerAddress = "0xbDA5747bFD65F08deb54cb465eB87D40e51B197E" 23 | let nftTransaction = await deployedPodShipNFT.mintNFT(targetOwnerAddress) 24 | await nftTransaction.wait(1) 25 | let currentTargetOwnerAddress = await deployedPodShipNFT.getNftOwner(1) 26 | assert.equal(currentTargetOwnerAddress, targetOwnerAddress) 27 | 28 | }) 29 | 30 | it("It should deploy successfully by setting platform fee to 5", async function () { 31 | let targetPlatformFee = "5"; 32 | let currentPlatformFee = await deployedPodShip.platformFee(); 33 | assert.equal(currentPlatformFee, targetPlatformFee); 34 | }) 35 | 36 | it("it should start an Auction successfully", async function () { 37 | let targetReservedPrice = "4" 38 | let auctionTxn = await deployedPodShip.startAuction(1, targetReservedPrice, 7, 5); 39 | await auctionTxn.wait(1) 40 | 41 | let auctions = await deployedPodShip.auctions[1] 42 | assert.equal(auctions.reservedPrice, targetReservedPrice) 43 | 44 | }) 45 | 46 | it("it should place a Bid", async function () { 47 | let targetReservedPrice = "1" 48 | let targetBid = "2" 49 | let targetOwnerAddress = "0xbDA5747bFD65F08deb54cb465eB87D40e51B197E" 50 | let nftTransaction = await deployedPodShipNFT.mintPodShipSupporterNFT(targetOwnerAddress) 51 | await nftTransaction.wait(1) 52 | let auctionTxn = await deployedPodShip.startAuction(1, targetReservedPrice, 7, 5); 53 | await auctionTxn.wait(1) 54 | 55 | let BidauctionTxn = await deployedPodShip.bid(1); 56 | await BidauctionTxn.wait(1) 57 | 58 | let auctions = await deployedPodShip.auctions[0] 59 | assert.equal(auctions.reservedPrice, targetReservedPrice) 60 | 61 | 62 | }) 63 | 64 | it("it should end an Auction successfully", async function () { 65 | let auctionTxn = await deployedPodShip.endAuction(0); 66 | await auctionTxn.wait(1) 67 | let auctions = await deployedPodShip.auctions[0] 68 | assert.isFalse(auctions.listed) 69 | 70 | }) 71 | 72 | it("it should cancel an Auction successfully", async function () { 73 | let auctionTxn = await deployedPodShip.cancelAuction(0); 74 | await auctionTxn.wait(1) 75 | let auctions = await deployedPodShip.auctions[0] 76 | assert.isFalse(auctions.listed) 77 | 78 | }) 79 | 80 | it("it should refund a bid successfully", async function () { 81 | let auctionTxn = await deployedPodShip.refundBid(0); 82 | await auctionTxn.wait(1) 83 | 84 | }) 85 | 86 | 87 | it("it should perform a check upkeep and know if upkeep is needed", async function () { 88 | let auctionTxn = await deployedPodShip.checkUpkeep(); 89 | await auctionTxn.wait(1) 90 | 91 | }) 92 | 93 | it("it should execute a perform upkeep function and know if upkeep is needed", async function () { 94 | let auctionTxn = await deployedPodShip.performUpkeep(); 95 | await auctionTxn.wait(1) 96 | 97 | }) 98 | 99 | it("it should fulfil random words", async function () { 100 | let auctionTxn = await deployedPodShip.fulfillRandomWords(1, "jay"); 101 | await auctionTxn.wait(1) 102 | 103 | }) 104 | 105 | it("it should change platform fee recipient", async function () { 106 | let targetPlatformFee = "5" 107 | let auctionTxn = await deployedPodShip.changePlatformFee(targetPlatformFee); 108 | await auctionTxn.wait(1) 109 | let currentPlatformFee = await deployedPodShip.platformFee() 110 | assert.equal(currentPlatformFee == targetPlatformFee) 111 | 112 | }) 113 | 114 | it("it should change platform fee", async function () { 115 | let targetPlatformFeeRecipient = "0xbDA5747bFD65F08deb54cb465eB87D40e51B197E" 116 | let auctionTxn = await deployedPodShip.changePlatformFeeRecipient(targetPlatformFeeRecipient); 117 | await auctionTxn.wait(1) 118 | 119 | let currentPlatformFeeRecipient = await deployedPodShip.platformFeeRecipient() 120 | assert.equal(currentPlatformFeeRecipient == targetPlatformFeeRecipient) 121 | 122 | }) 123 | 124 | it("it should Withdraw amount placed on Bid", async function () { 125 | let auctionTxn = await deployedPodShip.withdraw(); 126 | await auctionTxn.wait(1) 127 | 128 | }) 129 | }) 130 | --------------------------------------------------------------------------------