-
Notifications
You must be signed in to change notification settings - Fork 1
/
auction_with_creator.sol
154 lines (116 loc) · 4.71 KB
/
auction_with_creator.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
//SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.5.0 <0.9.0;
// this contract will deploy the Auction contract
contract AuctionCreator{
// declaring a dynamic array with addresses of deployed contracts
Auction[] public auctions;
// declaring the function that will deploy contract Auction
function createAuction() public{
// passing msg.sender to the constructor of Auction
Auction newAuction = new Auction(payable(msg.sender));
auctions.push(newAuction); // adding the address of the instance to the dynamic array
}
}
contract Auction{
address payable public owner;
uint public startBlock;
uint public endBlock;
string public ipfsHash;
enum State {Started, Running, Ended, Canceled}
State public auctionState;
uint public highestBindingBid;
address payable public highestBidder;
mapping(address => uint) public bids;
uint bidIncrement;
//the owner can finalize the auction and get the highestBindingBid only once
bool public ownerFinalized = false;
constructor(address payable eoa){
owner = eoa;
auctionState = State.Running;
startBlock = block.number;
endBlock = startBlock + 3;
ipfsHash = "";
bidIncrement = 1000000000000000000;
}
// declaring function modifiers
modifier notOwner(){
require(msg.sender != owner);
_;
}
modifier onlyOwner(){
require(msg.sender == owner);
_;
}
modifier afterStart(){
require(block.number >= startBlock);
_;
}
modifier beforeEnd(){
require(block.number <= endBlock);
_;
}
//a helper pure function (it neither reads, nor it writes to the blockchain)
function min(uint a, uint b) pure internal returns(uint){
if (a <= b){
return a;
}else{
return b;
}
}
// only the owner can cancel the Auction
function cancelAuction() public onlyOwner{
auctionState = State.Canceled;
}
// the main function called to place a bid
function placeBid() public payable notOwner afterStart beforeEnd returns(bool){
// to place a bid auction should be running
require(auctionState == State.Running);
// minimum value allowed to be sent
// require(msg.value > 0.0001 ether);
uint currentBid = bids[msg.sender] + msg.value;
// the currentBid should be greater than the highestBindingBid.
// Otherwise there's nothing to do.
require(currentBid > highestBindingBid);
// updating the mapping variable
bids[msg.sender] = currentBid;
if (currentBid <= bids[highestBidder]){ // highestBidder remains unchanged
highestBindingBid = min(currentBid + bidIncrement, bids[highestBidder]);
}else{ // highestBidder is another bidder
highestBindingBid = min(currentBid, bids[highestBidder] + bidIncrement);
highestBidder = payable(msg.sender);
}
return true;
}
function finalizeAuction() public{
// the auction has been Canceled or Ended
require(auctionState == State.Canceled || block.number > endBlock);
// only the owner or a bidder can cancel the auction
require(msg.sender == owner || bids[msg.sender] > 0);
// the recipient will get the value
address payable recipient;
uint value;
if(auctionState == State.Canceled){ // auction canceled, not ended
recipient = payable(msg.sender);
value = bids[msg.sender];
}else{// auction ended, not canceled
if(msg.sender == owner && ownerFinalized == false){ //the owner finalizes the auction
recipient = owner;
value = highestBindingBid;
//the owner can finalize the auction and get the highestBindingBid only once
ownerFinalized = true;
}else{// another user (not the owner) finalizes the auction
if (msg.sender == highestBidder){
recipient = highestBidder;
value = bids[highestBidder] - highestBindingBid;
}else{ //this is neither the owner nor the highest bidder (it's a regular bidder)
recipient = payable(msg.sender);
value = bids[msg.sender];
}
}
}
// resetting the bids of the recipient to avoid multiple transfers to the same recipient
bids[recipient] = 0;
//sends value to the recipient
recipient.transfer(value);
}
}