Complete the Dutch auction contract.
A NFT (non fungible token) is sold on a Dutch auction. A Dutch auction starts at the highest price set by the seller. The price of the NFT is lowered over time until someone buys it.
Copy // SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
interface IERC721 {
function transferFrom(
address _from,
address _to,
uint _nftId
) external;
}
contract DutchAuction {
uint private constant DURATION = 7 days;
IERC721 public immutable nft;
uint public immutable nftId;
address payable public immutable seller;
uint public immutable startingPrice;
uint public immutable startAt;
uint public immutable expiresAt;
uint public immutable discountRate;
constructor(
uint _startingPrice,
uint _discountRate,
address _nft,
uint _nftId
) {
seller = payable(msg.sender);
startingPrice = _startingPrice;
startAt = block.timestamp;
expiresAt = block.timestamp + DURATION;
discountRate = _discountRate;
require(
_startingPrice >= _discountRate * DURATION,
"starting price < min"
);
nft = IERC721(_nft);
nftId = _nftId;
}
function getPrice() public view returns (uint) {
uint timeElapsed = block.timestamp - startAt;
uint discount = discountRate * timeElapsed;
return startingPrice - discount;
}
function buy() external payable {
require(block.timestamp < expiresAt, "auction expired");
uint price = getPrice();
require(msg.value >= price, "ETH < price");
nft.transferFrom(seller, msg.sender, nftId);
uint refund = msg.value - price;
if (refund > 0) {
payable(msg.sender).transfer(refund);
}
selfdestruct(seller);
}
}
Copy function getPrice() public view returns (uint) {
uint timeElapsed = block.timestamp - startAt;
uint discount = discountRate * timeElapsed;
return startingPrice - discount;
}
The current price decrease linearly with time starting from the highest price.
Here is the equation.
Copy current price = starting price - (discount rate * time elapsed since start of auction)
Copy function buy() external payable {
require(block.timestamp < expiresAt, "auction expired");
uint price = getPrice();
require(msg.value >= price, "ETH < price");
nft.transferFrom(seller, msg.sender, nftId);
uint refund = msg.value - price;
if (refund > 0) {
payable(msg.sender).transfer(refund);
}
selfdestruct(seller);
}
Any user can buy the NFT with the following restrictions.