Allow truffle projects to contain vyper contracts (#571)
parent
c88eed29e7
commit
b6c483976e
@ -0,0 +1,82 @@ |
||||
# Open Auction |
||||
|
||||
# Auction params |
||||
# Beneficiary receives money from the highest bidder |
||||
beneficiary: public(address) |
||||
auctionStart: public(uint256) |
||||
auctionEnd: public(uint256) |
||||
|
||||
# Current state of auction |
||||
highestBidder: public(address) |
||||
highestBid: public(uint256) |
||||
|
||||
# Set to true at the end, disallows any change |
||||
ended: public(bool) |
||||
|
||||
# Keep track of refunded bids so we can follow the withdraw pattern |
||||
pendingReturns: public(HashMap[address, uint256]) |
||||
|
||||
# Create a simple auction with `_bidding_time` |
||||
# seconds bidding time on behalf of the |
||||
# beneficiary address `_beneficiary`. |
||||
@external |
||||
def __init__(_beneficiary: address, _bidding_time: uint256): |
||||
self.beneficiary = _beneficiary |
||||
self.auctionStart = block.timestamp |
||||
self.auctionEnd = self.auctionStart + _bidding_time |
||||
|
||||
# Bid on the auction with the value sent |
||||
# together with this transaction. |
||||
# The value will only be refunded if the |
||||
# auction is not won. |
||||
@external |
||||
@payable |
||||
def bid(): |
||||
# Check if bidding period is over. |
||||
assert block.timestamp < self.auctionEnd |
||||
# Check if bid is high enough |
||||
assert msg.value > self.highestBid |
||||
# Track the refund for the previous high bidder |
||||
self.pendingReturns[self.highestBidder] += self.highestBid |
||||
# Track new high bid |
||||
self.highestBidder = msg.sender |
||||
self.highestBid = msg.value |
||||
|
||||
# Withdraw a previously refunded bid. The withdraw pattern is |
||||
# used here to avoid a security issue. If refunds were directly |
||||
# sent as part of bid(), a malicious bidding contract could block |
||||
# those refunds and thus block new higher bids from coming in. |
||||
@external |
||||
def withdraw(): |
||||
pending_amount: uint256 = self.pendingReturns[msg.sender] |
||||
self.pendingReturns[msg.sender] = 0 |
||||
send(msg.sender, pending_amount) |
||||
|
||||
# End the auction and send the highest bid |
||||
# to the beneficiary. |
||||
@external |
||||
def endAuction(): |
||||
# It is a good guideline to structure functions that interact |
||||
# with other contracts (i.e. they call functions or send Ether) |
||||
# into three phases: |
||||
# 1. checking conditions |
||||
# 2. performing actions (potentially changing conditions) |
||||
# 3. interacting with other contracts |
||||
# If these phases are mixed up, the other contract could call |
||||
# back into the current contract and modify the state or cause |
||||
# effects (Ether payout) to be performed multiple times. |
||||
# If functions called internally include interaction with external |
||||
# contracts, they also have to be considered interaction with |
||||
# external contracts. |
||||
|
||||
# 1. Conditions |
||||
# Check if auction endtime has been reached |
||||
assert block.timestamp >= self.auctionEnd |
||||
# Check if this function has already been called |
||||
assert not self.ended |
||||
|
||||
# 2. Effects |
||||
self.ended = True |
||||
|
||||
# 3. Interaction |
||||
send(self.beneficiary, self.highestBid) |
Loading…
Reference in new issue