Auctions are a popular method to sell out the NFT collection drops at the best price possible.
There are a couple of auction techniques present in order to sell your NFT collection, but Dutch Auction is different from other techniques and is used more often.
Unlike a regular auction, in Dutch Auction, prices start very high and then slowly drop at predetermined time intervals.
In simpler words, in a Dutch Auction, the price of an NFT starts at an initial price (ceiling) and drops by a fixed amount periodically (eg. 0.1 ETH every 10 min) until it hits the lowest price it can go (the resting price)
Why Dutch Auction is so popular?
One of the reasons can be linked to the gas wars on the blockchain.
Gas wars are the spike in the blockchain gas fees that occurs when a high volume of transactions is initiated around the same time on blockchains like Ethereum, which has a low transaction throughput.
The Dutch auction style is used to redirect the excess minting fee from the miners towards the artists or channeled to fund specific charities or a community DAO.
So without anymore time, letโs write the Dutch Auction smart contract to sell our NFT!
Prerequisites:
In order to mint our NFT and sell it using Dutch Auction, we are going to create an NFT contract using one of our previous articles, and copy the contract from there.
Refer to this article or github repo to get the NFT smart contract.
Create a new file in your Remix IDE named as NFT.sol and paste the contract we used above.
Now we are good to go!
Letโs do some Dutch Auction ๐
1. Write our Smart Contract
Create a new solidity file in your Remix IDE and name it as DutchAuction.sol
Create an IERC-721 interface and then initialize your Dutch Auction contract.
Use the following code for reference:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
interface IERC721 {
function transferFrom(
address _from,
address _to,
uint _nftId
) external;
}
contract DutchAuction { }
Once youโve initialized your contract, we are going to define some variables that we have to use in our contract.
First, we are going to define the duration of the auction. That means the auction for the NFT will be expired after that duration. And we will define the duration for 2 days.
Next, we need to store the address of the NFT and its ID. Therefore, we will use IERC721 interface to store the NFT.
We made this variable immutable so that its value does not change once the contract is deployed.
Then, we going to store the address of the seller. Thus we will define the variable seller which will be storing the sellerโs address.
The Dutch Auction needs a starting price. So we are going to define a variable startingPrice
We also need the timestamp of when the auction starts and when the auction ends. Therefore, we will define 2 variables, startAt and expiresAt which will store the respective values.
-
Lastly, we will define the discountRate. DiscountRate will determine the rate at which the price decrements, starting from the startingPrice.
uint private constant DURATION = 2 days;
IERC721 public immutable nft;
uint public immutable nftId;
address public immutable seller;
uint public immutable startingPrice;
uint public immutable startAt;
uint public immutable expiresAt;
uint public immutable discountRate;
Next, we will initialize these state variables in a constructor.
Inside it, we are going to pass in the _startingPrice, _discountRate, _nft, and _nftId.
constructor(
uint _startingPrice,
uint _discountRate,
address _nft,
uint _nftId
) { }
-
Inside the constructor, we will set the seller to the deployer of this contract. And once the NFT will be sold, we need to transfer the ETH to the seller, therefore we will make it payable.
seller = payable(msg.sender);
-
We will take the input from the user to get the startingPrice, discountRate, startAt and expireAt. So, we will write it as:
startingPrice = _startingPrice;
discountRate = _discountRate;
startAt = block.timestamp;
expiresAt = block.timestamp + DURATION; -
We will also check whether the price of the NFT is always greater than zero or not.
_startingPrice >= _discountRate * DURATION, "Starting Price is less than the discount offered"
_discountRate * DURATION is the maximum amount of price deduction that is applied to the startingPrice
-
Lastly, we set the NFT using the input. So we can say:
nft = IERC721(_nft);
nftId = _nftId;
Now since our constructor is complete.
Next, weโre going to define 2 functions that we will be using further: currentPrice() and buyNow()
- Using currentPrice(), we will know the price of the NFT at that particular instance of time.
For that, we will write:
function currentPrice() public view returns (uint) {
uint timeElapsed = block.timestamp - startAt;
uint discount = discountRate * timeElapsed;
return startingPrice - discount;
}
-
Next, using the buyNow() function, the user will be able to buy the NFT.
function buy() external payable {
require(block.timestamp < expiresAt, "Auction expired! :(");
uint price = currentPrice();
require(msg.value >= price, "ETH is less than the price");
nft.transferFrom(seller, msg.sender, nftId);
selfdestruct(seller);
}
In this function, first, weโll check whether the auction is expired or not.
If the auction is not expired, then we will get the current price and store it inside the price variable using the currentPrice function.
Next, we will check that the amount we have sent is greater than or equal to the price.
Once we know that the msg.sender has sent enough ETH to buy the NFT, we will transfer the ownership of the NFT using the 3 parameters: seller, msg.sender, nftId.
Last but not the least, we have used the selfdestruct() function to close the auction. Therefore, we will pass the seller address inside the function.
Guess what?
We have completed our Dutch Auction Smart Contract!! ๐
Your contract should look like this ๐
Next, weโre going to test our Dutch Auction smart contract by selling our NFT. ๐ฎ
2. Mint our NFT using its tokenURI
Remember we created a file NFT.sol at the first place of this article?
Now we will deploy that NFT and then call the mint function using its tokenURI.
Once we have minted our demo NFT. Next we are going to deploy our Dutch Auction contract.
3. Deploy the Dutch Auction contract
Compile the Dutch Auction contract and then deploy it.
There are some parameters we have to pass in order to deploy our contract.
We will get the startingPrice to 1000000, discountRate at 1*,* the address of the NFT which we deployed just a while before and lastly, we have to provide the ***tokenId* which is equal to 1.
Once youโve added the parameters, hit the Deploy button to deploy our contract.
Once our Dutch Auction contract is deployed. Next thing weโre going to do is approve the Dutch Auction to spend our NFT.
For that, we will open our NFT under Deployed Contracts and execute the approve function.
We need to pass the Dutch Auctionโs deployed address and the tokenId of the NFT to run the approve function.
So now our DUTCH AUCTION HAS STARTED!!
To check whether the Dutch Auction has started or not, open the deployed Dutch Auction contract and run the currentPrice function several times. Youโll notice everytime you run the function, youโre getting a decremented price value.
Now its time to sell our NFT.
4. Sell our NFT using Dutch Auction contract
First, run the currentPrice function and copy the price value.
And then switch to some other account, from which you want to buy the NFT and paste the price value under the value option.
And then run the buyNow function.
GUESS WHAT!?
You just sold your NFT using Dutch Auction!! ๐
If you go back to your NFT contract and run the ownerOf function, you can see the owner of the contract is updated.
And this is how we can sell our NFT using the Dutch Auction!!!
If you liked the article, do give us a clap. ๐
And donโt worry, if you get any error message, you can ask us by tagging @uv_labs on Twitter.
Authors (open to feedback): ๐
Top comments (0)