Use-It-Or-Lose-It Slot Auction
use-it-or-lose-it-slot-auction · auction-allocation · 2011 B runtime · funds-movement
scores
- usefulness: 55
- safety: 35
- liveness: 30
- authenticity: 45
- extensibility: 40
- bytecodeDiscipline: 85
- practical: 48
source
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
contract SlotAuction {
address payable public beneficiary;
uint256 public deadline;
uint256 public timeout;
uint256 public penalty;
address payable public highestBidder;
uint256 public highestBid;
bool public executed;
bool public forfeited;
event BidPlaced(address indexed bidder, uint256 amount);
event Refunded(address indexed bidder, uint256 amount);
event Executed(address indexed winner, uint256 amount);
event Forfeited(address indexed winner, uint256 refund);
constructor(
address payable _beneficiary,
uint256 _deadline,
uint256 _timeoutDuration,
uint256 _penalty
) {
beneficiary = _beneficiary;
deadline = _deadline;
timeout = _deadline + _timeoutDuration;
penalty = _penalty;
}
function bid() external payable {
require(block.timestamp < deadline, "bidding closed");
require(msg.value > highestBid, "bid too low");
address payable previousBidder = highestBidder;
uint256 previousBid = highestBid;
highestBidder = payable(msg.sender);
highestBid = msg.value;
if (previousBidder != address(0)) {
(bool ok, ) = previousBidder.call{value: previousBid}("");
require(ok, "refund failed");
emit Refunded(previousBidder, previousBid);
}
emit BidPlaced(msg.sender, msg.value);
}
function execute() external {
require(!executed && !forfeited, "already closed");
require(block.timestamp >= deadline && block.timestamp < timeout, "not in window");
require(msg.sender == highestBidder, "not winner");
executed = true;
(bool ok, ) = beneficiary.call{value: highestBid}("");
require(ok, "beneficiary transfer failed");
emit Executed(msg.sender, highestBid);
}
function forfeit() external {
require(!executed && !forfeited, "already closed");
require(block.timestamp >= timeout, "too early");
require(msg.sender == highestBidder, "not winner");
require(highestBid >= penalty, "penalty too high");
forfeited = true;
uint256 refund = highestBid - penalty;
(bool ok, ) = payable(msg.sender).call{value: refund}("");
require(ok, "refund failed");
emit Forfeited(msg.sender, refund);
}
}