forked from Certora/Tutorials
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAuctionBroken.sol
113 lines (91 loc) · 3.45 KB
/
AuctionBroken.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
pragma solidity ^0.5.0;
/*
This example is based on a real bug from test version of the Maker MCD system
see https://www.certora.com/blog/why-testing-is-not-enough-for-million-dollar-code.html
*/
contract TokenInterface {
function mint(address who, uint amount) internal;
function transferTo(address _to, uint256 _value) public returns (bool success);
function getTotalSupply() public view returns (uint256);
}
library SafeMath {
function safeAdd(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
function safeSub(uint256 x, uint256 y) internal pure returns (uint256) {
assert(x >= y);
uint256 z = x - y;
return z;
}
}
contract Token is TokenInterface {
using SafeMath for uint256;
mapping (address => uint) balances;
uint public totalSupply;
function mint(address who, uint amount) internal {
balances[who] = balances[who].safeAdd(amount);
totalSupply = totalSupply.safeAdd(amount);
}
function transferTo(address _to, uint256 _value) public returns (bool success) {
if (balances[msg.sender] >= _value && _value > 0) {
balances[_to] = balances[_to].safeAdd(_value);
balances[msg.sender] = balances[msg.sender].safeSub(_value);
return true;
} else {
return false;
}
}
function balanceOf(address _owner) public view returns (uint) {
return balances[_owner];
}
function getTotalSupply() public view returns (uint) {
return totalSupply;
}
}
contract AuctionImpl is TokenInterface {
/*
Implementation of a reverse auction where bidders offer to take decreasing prize amounts for a fixed payment.
The bidder who has offered to take the lowest prize value is the winner.
The auction terminates after a fixed amount of time, or if no one submits a new winning bid for one hour.
Upon termination, the system mints an amount of tokens equal to the winning bid’s prize value, and transfers it to the winner.
*/
using SafeMath for uint256;
address public owner ;
modifier authorized { require(msg.sender == owner); _; }
struct AuctionStruct {
uint prize; // the prize decreasing by every bid
uint payment; // the payment to be paid by the last winner
address winner; //the current winner
uint bid_expiry;
uint end_time;
}
mapping (uint => AuctionStruct) auctions;
function getAuction(uint id) public view returns (uint,uint,address,uint,uint) {
return (auctions[id].prize, auctions[id].payment, auctions[id].winner,auctions[id].bid_expiry, auctions[id].end_time);
}
function newAuction(uint id, uint payment) public authorized {
require(auctions[id].end_time == 0); //check id in not occupied
auctions[id] = AuctionStruct(2**256-1,payment,owner, 0, now+1 days);
// arguments: prize, payment, winner, bid_expiry, end_time
}
function bid(uint id, uint b) public {
require(b < auctions[id].prize); // prize can only decrease
// new winner pays by repaying last winner
require(transferTo(auctions[id].winner, auctions[id].payment));
// update new winner with new prize
auctions[id].prize = b;
auctions[id].winner = msg.sender;
auctions[id].bid_expiry = now + 1 hours;
}
function close(uint id) public {
require(auctions[id].bid_expiry != 0
&& (auctions[id].bid_expiry < now ||
auctions[id].end_time < now));
mint(auctions[id].winner, auctions[id].prize);n
delete auctions[id];
}
}
contract System is Token, AuctionImpl {
}