Time-Slice State Auction
time-slice-state-auction · auction-allocation · 1627 B runtime · funds-movement
scores
- usefulness: 65
- safety: 55
- liveness: 70
- authenticity: 65
- extensibility: 30
- bytecodeDiscipline: 95
- practical: 63
source
pragma solidity ^0.8.13;
contract TimeSliceStateAuction {
uint256 public constant SLICE_LENGTH = 100;
uint256 public immutable genesis;
address public immutable owner;
bytes32 public state;
struct Auction {
uint96 highestBid;
address payable highestBidder;
}
Auction internal auction;
bytes32 public pendingValue;
uint32 public auctionSlice;
event Bid(address indexed bidder, uint256 amount, bytes32 value, uint32 indexed slice);
event Transition(address indexed winner, uint256 amount, bytes32 value, uint32 indexed slice);
constructor() {
genesis = block.number;
owner = msg.sender;
auctionSlice = 1;
}
function currentSlice() public view returns (uint32) {
return uint32((block.number - genesis) / SLICE_LENGTH);
}
function bid(bytes32 value) external payable {
require(msg.value > 0, "no bid");
require(msg.value <= type(uint96).max, "bid too large");
require(currentSlice() + 1 == auctionSlice, "wrong slice");
require(msg.value > auction.highestBid, "bid not higher");
auction.highestBid = uint96(msg.value);
auction.highestBidder = payable(msg.sender);
pendingValue = value;
emit Bid(msg.sender, msg.value, value, currentSlice());
}
function transition() external {
uint32 s = currentSlice();
require(s >= auctionSlice, "too early");
uint96 winningBid = auction.highestBid;
address winner = auction.highestBidder;
bytes32 value = pendingValue;
if (winningBid > 0) {
state = value;
}
delete auction;
pendingValue = bytes32(0);
auctionSlice = s + 1;
emit Transition(winner, winningBid, value, s);
}
function claimFees() external {
require(msg.sender == owner, "not owner");
payable(owner).transfer(address(this).balance);
}
}