Block-Slot Reservation Auction
block-slot-reservation-auction · auction-allocation · 1400 B runtime · funds-movement
scores
- usefulness: 45
- safety: 20
- liveness: 25
- authenticity: 40
- extensibility: 30
- bytecodeDiscipline: 85
- practical: 38
source
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
contract BlockSlotReservationAuction {
struct Reservation {
address bidder;
uint96 amount;
}
mapping(uint256 => Reservation) public reservations;
mapping(uint256 => bool) public claimed;
event BidPlaced(
uint64 indexed targetBlock,
uint128 indexed resourceId,
address indexed bidder,
uint256 amount,
address previousBidder,
uint256 previousAmount
);
event SlotClaimed(uint64 indexed targetBlock, uint128 indexed resourceId, address indexed bidder);
function bid(uint128 resourceId, uint64 targetBlock) external payable {
require(targetBlock >= block.number + 3);
uint96 amount = uint96(msg.value);
require(uint256(amount) == msg.value);
uint256 key = _key(targetBlock, resourceId);
Reservation storage r = reservations[key];
if (r.amount != 0) {
require(amount > r.amount);
address previousBidder = r.bidder;
uint96 previousAmount = r.amount;
r.bidder = msg.sender;
r.amount = amount;
(bool ok, ) = payable(previousBidder).call{value: previousAmount}("");
require(ok);
emit BidPlaced(targetBlock, resourceId, msg.sender, amount, previousBidder, previousAmount);
} else {
r.bidder = msg.sender;
r.amount = amount;
emit BidPlaced(targetBlock, resourceId, msg.sender, amount, address(0), 0);
}
}
function claimReservedSlot(uint128 resourceId, uint64 targetBlock) external {
require(targetBlock == block.number);
uint256 key = _key(targetBlock, resourceId);
Reservation storage r = reservations[key];
require(r.bidder == msg.sender);
require(!claimed[key]);
claimed[key] = true;
emit SlotClaimed(targetBlock, resourceId, msg.sender);
}
function reservation(uint128 resourceId, uint64 targetBlock)
external
view
returns (address bidder, uint256 amount, bool isClaimed)
{
uint256 key = _key(targetBlock, resourceId);
Reservation storage r = reservations[key];
return (r.bidder, r.amount, claimed[key]);
}
function _key(uint64 targetBlock, uint128 resourceId) internal pure returns (uint256) {
return (uint256(targetBlock) << 128) | uint256(resourceId);
}
}