Skip to content

Instantly share code, notes, and snippets.

@JhonatanHern
Created April 15, 2023 15:34
Show Gist options
  • Save JhonatanHern/f653e80afb9bb0943a8d7251cef58c4d to your computer and use it in GitHub Desktop.
Save JhonatanHern/f653e80afb9bb0943a8d7251cef58c4d to your computer and use it in GitHub Desktop.
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