// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract Auction {
event Start();
event Ended(address indexed highestBidder, uint bidAmount);
event Bid(address indexed sender, uint amount);
event Withdraw(address indexed bidder, uint amount);
address payable public seller;
bool public started;
bool public ended;
uint public endAt;
uint public highestBid;
address public highestBidder;
mapping(address => uint) public bids;
constructor () {
seller = payable(msg.sender);
}
function start() external{
require(msg.sender == seller, "You cannot start the bidding");
require(!started,"Auction is already started");
started = true;
highestBidder = msg.sender;
highestBid = 0;
endAt = block.timestamp + 2 days;
emit Start();
}
function end() external {
require(!ended, "This autction is already ended!");
require( block.timestamp >= endAt, "There is still time left");
ended = false;
emit Ended(highestBidder, highestBid);
}
function bid() external payable {
require(started, "Auction needs to be started first");
require(block.timestamp < endAt, "Auction ended");
require(msg.value > highestBid, "Bidding amount must be greater than current highest bid`");
highestBidder = msg.sender;
highestBid = msg.value;
if(highestBidder != address(0) ) { // 0000000000000000000
bids[highestBidder] += highestBid;
}
emit Bid(highestBidder, highestBid);
}
function withdraw() external payable {
uint bal = bids[msg.sender];
bids[msg.sender] = 0;
// bool sent = payable(msg.sender).send(bal);
// require(sent, "Failed to send Ether");
(bool sent, bytes memory data) = payable(msg.sender).call{value: msg.value}("");
require(sent, "Failed to send Ether");
emit Withdraw(msg.sender, bal);
}
}