// errors
struct AuctionAlreadyEnded {
}
struct AuctionNotYetEnded {
}
struct AuctionEndAlreadyCalled {}
struct BidNotHighEnough {
pub highest_bid: u256
}
// events
struct HighestBidIncreased {
#indexed
pub bidder: address
pub amount: u256
}
struct AuctionEnded {
#indexed
pub winner: address
pub amount: u256
}
contract Auction {
// states
auction_end_time: u256
beneficiary: address
highest_bidder: address
highest_bid: u256
pending_returns: Map<address, u256>
ended: bool
// constructor
pub fn __init__(mut self, ctx: Context, bidding_time: u256, beneficiary_addr: address) {
self.beneficiary = beneficiary_addr
self.auction_end_time = ctx.block_timestamp() + bidding_time
}
//method
pub fn bid(mut self, mut ctx: Context) {
if ctx.block_timestamp() > self.auction_end_time {
revert AuctionAlreadyEnded()
}
if ctx.msg_value() <= self.highest_bid {
revert BidNotHighEnough(highest_bid: self.highest_bid)
}
if self.highest_bid != 0 {
self.pending_returns[self.highest_bidder] += self.highest_bid
}
self.highest_bidder = ctx.msg_sender()
self.highest_bid = ctx.msg_value()
ctx.emit(HighestBidIncreased(bidder: ctx.msg_sender(), amount: ctx.msg_value()))
}
pub fn withdraw(mut self, mut ctx: Context) -> bool {
let amount: u256 = self.pending_returns[ctx.msg_sender()]
if amount > 0 {
self.pending_returns[ctx.msg_sender()] = 0
ctx.send_value(to: ctx.msg_sender(), wei: amount)
}
return true
}
pub fn auction_end(mut self, mut ctx: Context) {
if ctx.block_timestamp() <= self.auction_end_time {
revert AuctionNotYetEnded()
}
if self.ended {
revert AuctionEndAlreadyCalled()
}
self.ended = true
ctx.emit(AuctionEnded(winner: self.highest_bidder, amount: self.highest_bid))
ctx.send_value(to: self.beneficiary, wei: self.highest_bid)
}
pub fn check_highest_bidder(self) -> address {
return self.highest_bidder;
}
pub fn check_highest_bid(self) -> u256 {
return self.highest_bid;
}
pub fn check_ended(self) -> bool {
return self.ended;
}
}