-
Notifications
You must be signed in to change notification settings - Fork 133
/
Copy pathAugur.sol
393 lines (336 loc) · 22.7 KB
/
Augur.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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
pragma solidity 0.4.20;
import 'Controlled.sol';
import 'IAugur.sol';
import 'libraries/token/ERC20.sol';
import 'factories/UniverseFactory.sol';
import 'reporting/IUniverse.sol';
import 'reporting/IMarket.sol';
import 'reporting/IFeeWindow.sol';
import 'reporting/IReputationToken.sol';
import 'reporting/IReportingParticipant.sol';
import 'reporting/IDisputeCrowdsourcer.sol';
import 'reporting/IInitialReporter.sol';
import 'reporting/IMailbox.sol';
import 'trading/IShareToken.sol';
import 'trading/Order.sol';
// Centralized approval authority and event emissions
contract Augur is Controlled, IAugur {
enum TokenType{
ReputationToken,
ShareToken,
DisputeCrowdsourcer,
FeeWindow,
FeeToken
}
event MarketCreated(bytes32 indexed topic, string description, string extraInfo, address indexed universe, address market, address indexed marketCreator, bytes32[] outcomes, uint256 marketCreationFee, int256 minPrice, int256 maxPrice, IMarket.MarketType marketType);
event InitialReportSubmitted(address indexed universe, address indexed reporter, address indexed market, uint256 amountStaked, bool isDesignatedReporter, uint256[] payoutNumerators, bool invalid);
event DisputeCrowdsourcerCreated(address indexed universe, address indexed market, address disputeCrowdsourcer, uint256[] payoutNumerators, uint256 size, bool invalid);
event DisputeCrowdsourcerContribution(address indexed universe, address indexed reporter, address indexed market, address disputeCrowdsourcer, uint256 amountStaked);
event DisputeCrowdsourcerCompleted(address indexed universe, address indexed market, address disputeCrowdsourcer);
event InitialReporterRedeemed(address indexed universe, address indexed reporter, address indexed market, uint256 amountRedeemed, uint256 repReceived, uint256 reportingFeesReceived, uint256[] payoutNumerators);
event DisputeCrowdsourcerRedeemed(address indexed universe, address indexed reporter, address indexed market, address disputeCrowdsourcer, uint256 amountRedeemed, uint256 repReceived, uint256 reportingFeesReceived, uint256[] payoutNumerators);
event ReportingParticipantDisavowed(address indexed universe, address indexed market, address reportingParticipant);
event MarketParticipantsDisavowed(address indexed universe, address indexed market);
event FeeWindowRedeemed(address indexed universe, address indexed reporter, address indexed feeWindow, uint256 amountRedeemed, uint256 reportingFeesReceived);
event MarketFinalized(address indexed universe, address indexed market);
event MarketMigrated(address indexed market, address indexed originalUniverse, address indexed newUniverse);
event UniverseForked(address indexed universe);
event UniverseCreated(address indexed parentUniverse, address indexed childUniverse, uint256[] payoutNumerators, bool invalid);
event OrderCanceled(address indexed universe, address indexed shareToken, address indexed sender, bytes32 orderId, Order.Types orderType, uint256 tokenRefund, uint256 sharesRefund);
// The ordering here is to match functions higher in the call chain to avoid stack depth issues
event OrderCreated(Order.Types orderType, uint256 amount, uint256 price, address indexed creator, uint256 moneyEscrowed, uint256 sharesEscrowed, bytes32 tradeGroupId, bytes32 orderId, address indexed universe, address indexed shareToken);
event OrderFilled(address indexed universe, address indexed shareToken, address filler, bytes32 orderId, uint256 numCreatorShares, uint256 numCreatorTokens, uint256 numFillerShares, uint256 numFillerTokens, uint256 marketCreatorFees, uint256 reporterFees, uint256 amountFilled, bytes32 tradeGroupId);
event CompleteSetsPurchased(address indexed universe, address indexed market, address indexed account, uint256 numCompleteSets);
event CompleteSetsSold(address indexed universe, address indexed market, address indexed account, uint256 numCompleteSets);
event TradingProceedsClaimed(address indexed universe, address indexed shareToken, address indexed sender, address market, uint256 numShares, uint256 numPayoutTokens, uint256 finalTokenBalance);
event TokensTransferred(address indexed universe, address indexed token, address indexed from, address to, uint256 value, TokenType tokenType, address market);
event TokensMinted(address indexed universe, address indexed token, address indexed target, uint256 amount, TokenType tokenType, address market);
event TokensBurned(address indexed universe, address indexed token, address indexed target, uint256 amount, TokenType tokenType, address market);
event FeeWindowCreated(address indexed universe, address feeWindow, uint256 startTime, uint256 endTime, uint256 id);
event InitialReporterTransferred(address indexed universe, address indexed market, address from, address to);
event MarketTransferred(address indexed universe, address indexed market, address from, address to);
event MarketMailboxTransferred(address indexed universe, address indexed market, address indexed mailbox, address from, address to);
event EscapeHatchChanged(bool isOn);
event TimestampSet(uint256 newTimestamp);
mapping(address => bool) private universes;
mapping(address => bool) private crowdsourcers;
//
// Universe
//
function createGenesisUniverse() public returns (IUniverse) {
return createUniverse(IUniverse(0), bytes32(0), new uint256[](0), false);
}
function createChildUniverse(bytes32 _parentPayoutDistributionHash, uint256[] _parentPayoutNumerators, bool _parentInvalid) public returns (IUniverse) {
IUniverse _parentUniverse = IUniverse(msg.sender);
require(isKnownUniverse(_parentUniverse));
return createUniverse(_parentUniverse, _parentPayoutDistributionHash, _parentPayoutNumerators, _parentInvalid);
}
function createUniverse(IUniverse _parentUniverse, bytes32 _parentPayoutDistributionHash, uint256[] _parentPayoutNumerators, bool _parentInvalid) private returns (IUniverse) {
UniverseFactory _universeFactory = UniverseFactory(controller.lookup("UniverseFactory"));
IUniverse _newUniverse = _universeFactory.createUniverse(controller, _parentUniverse, _parentPayoutDistributionHash);
universes[_newUniverse] = true;
UniverseCreated(_parentUniverse, _newUniverse, _parentPayoutNumerators, _parentInvalid);
return _newUniverse;
}
function isKnownUniverse(IUniverse _universe) public view returns (bool) {
return universes[_universe];
}
//
// Crowdsourcers
//
function isKnownCrowdsourcer(IDisputeCrowdsourcer _crowdsourcer) public view returns (bool) {
return crowdsourcers[_crowdsourcer];
}
function disputeCrowdsourcerCreated(IUniverse _universe, address _market, address _disputeCrowdsourcer, uint256[] _payoutNumerators, uint256 _size, bool _invalid) public returns (bool) {
require(isKnownUniverse(_universe));
require(_universe.isContainerForMarket(IMarket(msg.sender)));
crowdsourcers[_disputeCrowdsourcer] = true;
DisputeCrowdsourcerCreated(_universe, _market, _disputeCrowdsourcer, _payoutNumerators, _size, _invalid);
return true;
}
//
// Transfer
//
function trustedTransfer(ERC20 _token, address _from, address _to, uint256 _amount) public onlyWhitelistedCallers returns (bool) {
require(_amount > 0);
require(_token.transferFrom(_from, _to, _amount));
return true;
}
//
// Logging
//
// This signature is intended for the categorical market creation. We use two signatures for the same event because of stack depth issues which can be circumvented by maintaining order of paramaters
function logMarketCreated(bytes32 _topic, string _description, string _extraInfo, IUniverse _universe, address _market, address _marketCreator, bytes32[] _outcomes, int256 _minPrice, int256 _maxPrice, IMarket.MarketType _marketType) public returns (bool) {
require(isKnownUniverse(_universe));
require(_universe == IUniverse(msg.sender));
MarketCreated(_topic, _description, _extraInfo, _universe, _market, _marketCreator, _outcomes, _universe.getOrCacheMarketCreationCost(), _minPrice, _maxPrice, _marketType);
return true;
}
// This signature is intended for yesNo and scalar market creation. See function comment above for explanation.
function logMarketCreated(bytes32 _topic, string _description, string _extraInfo, IUniverse _universe, address _market, address _marketCreator, int256 _minPrice, int256 _maxPrice, IMarket.MarketType _marketType) public returns (bool) {
require(isKnownUniverse(_universe));
require(_universe == IUniverse(msg.sender));
MarketCreated(_topic, _description, _extraInfo, _universe, _market, _marketCreator, new bytes32[](0), _universe.getOrCacheMarketCreationCost(), _minPrice, _maxPrice, _marketType);
return true;
}
function logInitialReportSubmitted(IUniverse _universe, address _reporter, address _market, uint256 _amountStaked, bool _isDesignatedReporter, uint256[] _payoutNumerators, bool _invalid) public returns (bool) {
require(isKnownUniverse(_universe));
require(_universe.isContainerForMarket(IMarket(msg.sender)));
InitialReportSubmitted(_universe, _reporter, _market, _amountStaked, _isDesignatedReporter, _payoutNumerators, _invalid);
return true;
}
function logDisputeCrowdsourcerContribution(IUniverse _universe, address _reporter, address _market, address _disputeCrowdsourcer, uint256 _amountStaked) public returns (bool) {
require(isKnownUniverse(_universe));
require(_universe.isContainerForMarket(IMarket(msg.sender)));
DisputeCrowdsourcerContribution(_universe, _reporter, _market, _disputeCrowdsourcer, _amountStaked);
return true;
}
function logDisputeCrowdsourcerCompleted(IUniverse _universe, address _market, address _disputeCrowdsourcer) public returns (bool) {
require(isKnownUniverse(_universe));
require(_universe.isContainerForMarket(IMarket(msg.sender)));
DisputeCrowdsourcerCompleted(_universe, _market, _disputeCrowdsourcer);
return true;
}
function logInitialReporterRedeemed(IUniverse _universe, address _reporter, address _market, uint256 _amountRedeemed, uint256 _repReceived, uint256 _reportingFeesReceived, uint256[] _payoutNumerators) public returns (bool) {
require(isKnownUniverse(_universe));
require(_universe.isContainerForReportingParticipant(IReportingParticipant(msg.sender)));
InitialReporterRedeemed(_universe, _reporter, _market, _amountRedeemed, _repReceived, _reportingFeesReceived, _payoutNumerators);
return true;
}
function logDisputeCrowdsourcerRedeemed(IUniverse _universe, address _reporter, address _market, uint256 _amountRedeemed, uint256 _repReceived, uint256 _reportingFeesReceived, uint256[] _payoutNumerators) public returns (bool) {
IDisputeCrowdsourcer _disputeCrowdsourcer = IDisputeCrowdsourcer(msg.sender);
require(isKnownCrowdsourcer(_disputeCrowdsourcer));
DisputeCrowdsourcerRedeemed(_universe, _reporter, _market, _disputeCrowdsourcer, _amountRedeemed, _repReceived, _reportingFeesReceived, _payoutNumerators);
return true;
}
function logReportingParticipantDisavowed(IUniverse _universe, IMarket _market) public returns (bool) {
require(isKnownUniverse(_universe));
require(_universe.isContainerForReportingParticipant(IReportingParticipant(msg.sender)));
ReportingParticipantDisavowed(_universe, _market, msg.sender);
return true;
}
function logMarketParticipantsDisavowed(IUniverse _universe) public returns (bool) {
require(isKnownUniverse(_universe));
IMarket _market = IMarket(msg.sender);
require(_universe.isContainerForMarket(_market));
MarketParticipantsDisavowed(_universe, _market);
return true;
}
function logFeeWindowRedeemed(IUniverse _universe, address _reporter, uint256 _amountRedeemed, uint256 _reportingFeesReceived) public returns (bool) {
require(isKnownUniverse(_universe));
require(_universe.isContainerForFeeWindow(IFeeWindow(msg.sender)));
FeeWindowRedeemed(_universe, _reporter, msg.sender, _amountRedeemed, _reportingFeesReceived);
return true;
}
function logMarketFinalized(IUniverse _universe) public returns (bool) {
require(isKnownUniverse(_universe));
IMarket _market = IMarket(msg.sender);
require(_universe.isContainerForMarket(_market));
MarketFinalized(_universe, _market);
return true;
}
function logMarketMigrated(IMarket _market, IUniverse _originalUniverse) public returns (bool) {
IUniverse _newUniverse = IUniverse(msg.sender);
require(isKnownUniverse(_newUniverse));
MarketMigrated(_market, _originalUniverse, _newUniverse);
return true;
}
function logOrderCanceled(IUniverse _universe, address _shareToken, address _sender, bytes32 _orderId, Order.Types _orderType, uint256 _tokenRefund, uint256 _sharesRefund) public onlyWhitelistedCallers returns (bool) {
OrderCanceled(_universe, _shareToken, _sender, _orderId, _orderType, _tokenRefund, _sharesRefund);
return true;
}
function logOrderCreated(Order.Types _orderType, uint256 _amount, uint256 _price, address _creator, uint256 _moneyEscrowed, uint256 _sharesEscrowed, bytes32 _tradeGroupId, bytes32 _orderId, IUniverse _universe, address _shareToken) public onlyWhitelistedCallers returns (bool) {
OrderCreated(_orderType, _amount, _price, _creator, _moneyEscrowed, _sharesEscrowed, _tradeGroupId, _orderId, _universe, _shareToken);
return true;
}
function logOrderFilled(IUniverse _universe, address _shareToken, address _filler, bytes32 _orderId, uint256 _numCreatorShares, uint256 _numCreatorTokens, uint256 _numFillerShares, uint256 _numFillerTokens, uint256 _marketCreatorFees, uint256 _reporterFees, uint256 _amountFilled, bytes32 _tradeGroupId) public onlyWhitelistedCallers returns (bool) {
OrderFilled(_universe, _shareToken, _filler, _orderId, _numCreatorShares, _numCreatorTokens, _numFillerShares, _numFillerTokens, _marketCreatorFees, _reporterFees, _amountFilled, _tradeGroupId);
return true;
}
function logCompleteSetsPurchased(IUniverse _universe, IMarket _market, address _account, uint256 _numCompleteSets) public onlyWhitelistedCallers returns (bool) {
CompleteSetsPurchased(_universe, _market, _account, _numCompleteSets);
return true;
}
function logCompleteSetsSold(IUniverse _universe, IMarket _market, address _account, uint256 _numCompleteSets) public onlyWhitelistedCallers returns (bool) {
CompleteSetsSold(_universe, _market, _account, _numCompleteSets);
return true;
}
function logTradingProceedsClaimed(IUniverse _universe, address _shareToken, address _sender, address _market, uint256 _numShares, uint256 _numPayoutTokens, uint256 _finalTokenBalance) public onlyWhitelistedCallers returns (bool) {
TradingProceedsClaimed(_universe, _shareToken, _sender, _market, _numShares, _numPayoutTokens, _finalTokenBalance);
return true;
}
function logUniverseForked() public returns (bool) {
require(universes[msg.sender]);
UniverseForked(msg.sender);
return true;
}
function logFeeWindowTransferred(IUniverse _universe, address _from, address _to, uint256 _value) public returns (bool) {
require(isKnownUniverse(_universe));
require(_universe.isContainerForFeeWindow(IFeeWindow(msg.sender)));
TokensTransferred(_universe, msg.sender, _from, _to, _value, TokenType.FeeWindow, 0);
return true;
}
function logReputationTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value) public returns (bool) {
require(isKnownUniverse(_universe));
require(_universe.getReputationToken() == IReputationToken(msg.sender));
TokensTransferred(_universe, msg.sender, _from, _to, _value, TokenType.ReputationToken, 0);
return true;
}
function logDisputeCrowdsourcerTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value) public returns (bool) {
IDisputeCrowdsourcer _disputeCrowdsourcer = IDisputeCrowdsourcer(msg.sender);
require(isKnownCrowdsourcer(_disputeCrowdsourcer));
TokensTransferred(_universe, msg.sender, _from, _to, _value, TokenType.DisputeCrowdsourcer, _disputeCrowdsourcer.getMarket());
return true;
}
function logShareTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value) public returns (bool) {
require(isKnownUniverse(_universe));
IShareToken _shareToken = IShareToken(msg.sender);
require(_universe.isContainerForShareToken(_shareToken));
TokensTransferred(_universe, msg.sender, _from, _to, _value, TokenType.ShareToken, _shareToken.getMarket());
return true;
}
function logReputationTokenBurned(IUniverse _universe, address _target, uint256 _amount) public returns (bool) {
require(isKnownUniverse(_universe));
require(_universe.getReputationToken() == IReputationToken(msg.sender));
TokensBurned(_universe, msg.sender, _target, _amount, TokenType.ReputationToken, 0);
return true;
}
function logReputationTokenMinted(IUniverse _universe, address _target, uint256 _amount) public returns (bool) {
require(isKnownUniverse(_universe));
require(_universe.getReputationToken() == IReputationToken(msg.sender));
TokensMinted(_universe, msg.sender, _target, _amount, TokenType.ReputationToken, 0);
return true;
}
function logShareTokenBurned(IUniverse _universe, address _target, uint256 _amount) public returns (bool) {
require(isKnownUniverse(_universe));
IShareToken _shareToken = IShareToken(msg.sender);
require(_universe.isContainerForShareToken(_shareToken));
TokensBurned(_universe, msg.sender, _target, _amount, TokenType.ShareToken, _shareToken.getMarket());
return true;
}
function logShareTokenMinted(IUniverse _universe, address _target, uint256 _amount) public returns (bool) {
require(isKnownUniverse(_universe));
IShareToken _shareToken = IShareToken(msg.sender);
require(_universe.isContainerForShareToken(_shareToken));
TokensMinted(_universe, msg.sender, _target, _amount, TokenType.ShareToken, _shareToken.getMarket());
return true;
}
function logFeeWindowBurned(IUniverse _universe, address _target, uint256 _amount) public returns (bool) {
require(isKnownUniverse(_universe));
require(_universe.isContainerForFeeWindow(IFeeWindow(msg.sender)));
TokensBurned(_universe, msg.sender, _target, _amount, TokenType.FeeWindow, 0);
return true;
}
function logFeeWindowMinted(IUniverse _universe, address _target, uint256 _amount) public returns (bool) {
require(isKnownUniverse(_universe));
require(_universe.isContainerForFeeWindow(IFeeWindow(msg.sender)));
TokensMinted(_universe, msg.sender, _target, _amount, TokenType.FeeWindow, 0);
return true;
}
function logDisputeCrowdsourcerTokensBurned(IUniverse _universe, address _target, uint256 _amount) public returns (bool) {
IDisputeCrowdsourcer _disputeCrowdsourcer = IDisputeCrowdsourcer(msg.sender);
require(isKnownCrowdsourcer(_disputeCrowdsourcer));
TokensBurned(_universe, msg.sender, _target, _amount, TokenType.DisputeCrowdsourcer, _disputeCrowdsourcer.getMarket());
return true;
}
function logDisputeCrowdsourcerTokensMinted(IUniverse _universe, address _target, uint256 _amount) public returns (bool) {
IDisputeCrowdsourcer _disputeCrowdsourcer = IDisputeCrowdsourcer(msg.sender);
require(isKnownCrowdsourcer(_disputeCrowdsourcer));
TokensMinted(_universe, msg.sender, _target, _amount, TokenType.DisputeCrowdsourcer, _disputeCrowdsourcer.getMarket());
return true;
}
function logFeeWindowCreated(IFeeWindow _feeWindow, uint256 _id) public returns (bool) {
require(universes[msg.sender]);
FeeWindowCreated(msg.sender, _feeWindow, _feeWindow.getStartTime(), _feeWindow.getEndTime(), _id);
return true;
}
function logFeeTokenTransferred(IUniverse _universe, address _from, address _to, uint256 _value) public returns (bool) {
require(isKnownUniverse(_universe));
require(_universe.isContainerForFeeToken(IFeeToken(msg.sender)));
TokensTransferred(_universe, msg.sender, _from, _to, _value, TokenType.FeeToken, 0);
return true;
}
function logFeeTokenBurned(IUniverse _universe, address _target, uint256 _amount) public returns (bool) {
require(isKnownUniverse(_universe));
require(_universe.isContainerForFeeToken(IFeeToken(msg.sender)));
TokensBurned(_universe, msg.sender, _target, _amount, TokenType.FeeToken, 0);
return true;
}
function logFeeTokenMinted(IUniverse _universe, address _target, uint256 _amount) public returns (bool) {
require(isKnownUniverse(_universe));
require(_universe.isContainerForFeeToken(IFeeToken(msg.sender)));
TokensMinted(_universe, msg.sender, _target, _amount, TokenType.FeeToken, 0);
return true;
}
function logTimestampSet(uint256 _newTimestamp) public returns (bool) {
require(msg.sender == controller.lookup("Time"));
TimestampSet(_newTimestamp);
return true;
}
function logInitialReporterTransferred(IUniverse _universe, IMarket _market, address _from, address _to) public returns (bool) {
require(isKnownUniverse(_universe));
require(_universe.isContainerForMarket(_market));
require(msg.sender == _market.getInitialReporterAddress());
InitialReporterTransferred(_universe, _market, _from, _to);
return true;
}
function logMarketTransferred(IUniverse _universe, address _from, address _to) public returns (bool) {
require(isKnownUniverse(_universe));
IMarket _market = IMarket(msg.sender);
require(_universe.isContainerForMarket(_market));
MarketTransferred(_universe, _market, _from, _to);
return true;
}
function logMarketMailboxTransferred(IUniverse _universe, IMarket _market, address _from, address _to) public returns (bool) {
require(isKnownUniverse(_universe));
require(_universe.isContainerForMarket(_market));
require(IMailbox(msg.sender) == _market.getMarketCreatorMailbox());
MarketMailboxTransferred(_universe, _market, msg.sender, _from, _to);
return true;
}
function logEscapeHatchChanged(bool _isOn) public returns (bool) {
require(msg.sender == address(controller));
EscapeHatchChanged(_isOn);
return true;
}
}