55荷兰拍卖

规则:随着时间的流逝,价格越来越低。(eg。郁金香)

谁最先出价就可以得到拍卖品。

// SPDX-License-Identifier: MIT
pragma solidity 0.8.18;
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
    ){
        // 销售成功后,要把主币发送给发送者,所以发送者要增加payable属性
        seller=payable(msg.sender);
        startingPrice=_startingPrice;
        discountRate=_discountRate;
        startAt=block.timestamp;
        expiresAt=block.timestamp+DURATION;
        require(
            _startingPrice>=_discountRate*DURATION,
            "starting price < discount"
        );
        nft=IERC721(_nft);
        nftId=_nftId;
    }
    // 查看nft价格
    function getPrice()public view returns (uint){
        // 流逝的时间
        uint timeElasped=block.timestamp-startAt;
        uint discount=discountRate*timeElasped;
        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);
    }

}