Created
April 15, 2023 15:34
-
-
Save JhonatanHern/f653e80afb9bb0943a8d7251cef58c4d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.8.0; | |
import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; | |
import "@openzeppelin/contracts/access/Ownable.sol"; | |
import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; | |
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; | |
contract MyNFT is ERC721, Ownable { | |
using SafeERC20 for IERC20; | |
// Auction struct to store auction details | |
struct Auction { | |
uint256 highestBid; | |
address paymentTokenAddress; | |
address highestBidder; | |
uint256 auctionEndTime; | |
} | |
// Mapping to store auctions | |
mapping(uint256 => Auction) public auctions; | |
// Whitelist of addresses that can create auctions | |
mapping(address => bool) public auctionWhitelist; | |
// Mapping to store the highest bidder for each auction | |
mapping(uint256 => address) public highestBidders; | |
// Event for logging new auctions | |
event NewAuction(uint256 tokenId, address paymentTokenAddress, uint256 auctionEndTime); | |
// Event for logging new bid | |
event NewBid(uint256 tokenId, address bidder, uint256 amount); | |
constructor(string memory _name, string memory _symbol) ERC721(_name, _symbol) {} | |
/** | |
* @dev Creates a new auction for the given token ID. | |
* | |
* Requirements: | |
* | |
* - Caller must be whitelisted. | |
* - Caller must be the owner of the token. | |
* - Auction end time must be in the future. | |
*/ | |
function createAuction( | |
uint256 _tokenId, | |
address _paymentTokenAddress, | |
uint256 _auctionEndTime | |
) external onlyWhitelisted { | |
require(ownerOf(_tokenId) == msg.sender, "Only the owner of the token can create an auction for it."); | |
require(_auctionEndTime > block.timestamp, "Auction end time must be in the future"); | |
auctions[_tokenId] = Auction({ | |
highestBid: 0, | |
paymentTokenAddress: _paymentTokenAddress, | |
highestBidder: address(0), | |
auctionEndTime: _auctionEndTime | |
}); | |
emit NewAuction(_tokenId, _paymentTokenAddress, _auctionEndTime); | |
} | |
/** | |
* @dev Places a bid on an existing auction for the given token ID. | |
* | |
* Requirements: | |
* | |
* - Bid must be higher than the current highest bid. | |
* - Auction must not have ended. | |
*/ | |
function placeBid(uint256 _tokenId, uint256 _bidAmount) external { | |
Auction storage auction = auctions[_tokenId]; | |
require(auction.auctionEndTime > block.timestamp, "Auction has already ended."); | |
require(auction.highestBid < _bidAmount, "Your bid must be higher than the current highest bid."); | |
if(auction.highestBidder != address(0)){ | |
IERC20(auction.paymentTokenAddress).safeTransfer(auction.highestBidder, auction.highestBid); | |
} | |
IERC20(auction.paymentTokenAddress).safeTransferFrom(msg.sender, address(this), _bidAmount); | |
auction.highestBid = _bidAmount; | |
auction.highestBidder = msg.sender; | |
highestBidders[_tokenId] = msg.sender; | |
emit NewBid(_tokenId, msg.sender, _bidAmount); | |
} | |
/** | |
* @dev Adds an address to the auction whitelist. | |
*/ | |
function addToWhitelist(address _address) external onlyOwner { | |
auctionWhitelist[_address] = true; | |
} | |
/** | |
* @dev Removes an address from the auction whitelist. | |
*/ | |
function removeFromWhitelist(address _address) external onlyOwner { | |
auctionWhitelist[_address] = false; | |
} | |
/** | |
* @dev Withdraws the NFT from the contract after the auction has ended. | |
* | |
* Requirements: | |
* | |
* - Auction must have ended. | |
* - There must be no bids on the auction. | |
*/ | |
function withdrawNFT(uint256 _tokenId) external onlyOwner { | |
require(auctions[_tokenId].highestBid == 0, "Cannot withdraw NFT until auction has ended."); | |
safeTransferFrom(address(this), msg.sender, _tokenId); | |
} | |
/** | |
* @dev Ends an auction for the given token ID. | |
* | |
* Requirements: | |
* | |
* - Auction must have ended. | |
* - There must be at least one bid on the auction. | |
*/ | |
function endAuction(uint256 _tokenId) external { | |
Auction storage auction = auctions[_tokenId]; | |
require(auction.auctionEndTime < block.timestamp, "Auction has not ended yet."); | |
require(highestBidders[_tokenId] != address(0), "No bids have been placed."); | |
IERC20(auction.paymentTokenAddress).safeTransfer(ownerOf(_tokenId), auction.highestBid); | |
safeTransferFrom(address(this), highestBidders[_tokenId], _tokenId); | |
delete auctions[_tokenId]; | |
} | |
// Function to retrieve the highest bid for an auction | |
function getHighestBid(uint256 _tokenId) external view returns (uint256) { | |
return auctions[_tokenId].highestBid; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment