Block Slot Auction
block-slot-auction · auction-allocation · 1415 B runtime · funds-movement
scores
- usefulness: 5
- safety: 4
- liveness: 5
- authenticity: 6
- extensibility: 3
- bytecodeDiscipline: 7
- practical: 5
source
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
contract BlockSlotAuction {
mapping(uint256 => address) public winnerOfSlot;
uint256 public activeSlot;
address public activeBidder;
uint256 public activeBid;
mapping(address => uint256) public refunds;
event Bid(address indexed bidder, uint256 amount, uint256 targetBlock);
event SlotWinner(uint256 indexed blockNumber, address indexed winner, uint256 bid);
event Executed(uint256 indexed blockNumber, address indexed executor);
function bid() external payable {
_finalizePriorSlot();
uint256 target = block.number + 1;
if (activeSlot != target) {
activeSlot = target;
activeBidder = address(0);
activeBid = 0;
}
require(msg.value > activeBid, 'bid too low');
if (activeBidder != address(0)) {
refunds[activeBidder] += activeBid;
}
activeBidder = msg.sender;
activeBid = msg.value;
emit Bid(msg.sender, msg.value, target);
}
function execute() external {
_finalizePriorSlot();
require(winnerOfSlot[block.number] == msg.sender, 'not winner');
emit Executed(block.number, msg.sender);
}
function withdraw() external {
uint256 amount = refunds[msg.sender];
require(amount > 0, 'no refund');
refunds[msg.sender] = 0;
(bool ok, ) = msg.sender.call{value: amount}('');
require(ok, 'transfer failed');
}
function _finalizePriorSlot() private {
if (activeSlot == 0 || activeSlot > block.number) return;
if (winnerOfSlot[activeSlot] == address(0)) {
winnerOfSlot[activeSlot] = activeBidder;
emit SlotWinner(activeSlot, activeBidder, activeBid);
}
activeBidder = address(0);
activeBid = 0;
activeSlot = 0;
}
}