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
|
pragma solidity ^0.4.11;
import "../Tokens/Token.sol";
import "../Tokens/OutcomeToken.sol";
import "../Oracles/Oracle.sol";
/// @title Event contract - Provide basic functionality required by different event types
/// @author Stefan George - <stefan@gnosis.pm>
contract Event {
/*
* Events
*/
event OutcomeTokenCreation(OutcomeToken outcomeToken, uint8 index);
event OutcomeTokenSetIssuance(address indexed buyer, uint collateralTokenCount);
event OutcomeTokenSetRevocation(address indexed seller, uint outcomeTokenCount);
event OutcomeAssignment(int outcome);
event WinningsRedemption(address indexed receiver, uint winnings);
/*
* Storage
*/
Token public collateralToken;
Oracle public oracle;
bool public isOutcomeSet;
int public outcome;
OutcomeToken[] public outcomeTokens;
/*
* Public functions
*/
/// @dev Contract constructor validates and sets basic event properties
/// @param _collateralToken Tokens used as collateral in exchange for outcome tokens
/// @param _oracle Oracle contract used to resolve the event
/// @param outcomeCount Number of event outcomes
constructor(Token _collateralToken, Oracle _oracle, uint8 outcomeCount)
public
{
// Validate input
require(address(_collateralToken) != address(0) && address(_oracle) != address(0) && outcomeCount >= 2);
collateralToken = _collateralToken;
oracle = _oracle;
// Create an outcome token for each outcome
for (uint8 i = 0; i < outcomeCount; i++) {
OutcomeToken outcomeToken = new OutcomeToken();
outcomeTokens.push(outcomeToken);
emit OutcomeTokenCreation(outcomeToken, i);
}
}
/// @dev Buys equal number of tokens of all outcomes, exchanging collateral tokens and sets of outcome tokens 1:1
/// @param collateralTokenCount Number of collateral tokens
function buyAllOutcomes(uint collateralTokenCount)
public
{
// Transfer collateral tokens to events contract
require(collateralToken.transferFrom(msg.sender, this, collateralTokenCount));
// Issue new outcome tokens to sender
for (uint8 i = 0; i < outcomeTokens.length; i++)
outcomeTokens[i].issue(msg.sender, collateralTokenCount);
emit OutcomeTokenSetIssuance(msg.sender, collateralTokenCount);
}
/// @dev Sells equal number of tokens of all outcomes, exchanging collateral tokens and sets of outcome tokens 1:1
/// @param outcomeTokenCount Number of outcome tokens
function sellAllOutcomes(uint outcomeTokenCount)
public
{
// Revoke sender's outcome tokens of all outcomes
for (uint8 i = 0; i < outcomeTokens.length; i++)
outcomeTokens[i].revoke(msg.sender, outcomeTokenCount);
// Transfer collateral tokens to sender
require(collateralToken.transfer(msg.sender, outcomeTokenCount));
emit OutcomeTokenSetRevocation(msg.sender, outcomeTokenCount);
}
/// @dev Sets winning event outcome
function setOutcome()
public
{
// Winning outcome is not set yet in event contract but in oracle contract
require(!isOutcomeSet && oracle.isOutcomeSet());
// Set winning outcome
outcome = oracle.getOutcome();
isOutcomeSet = true;
emit OutcomeAssignment(outcome);
}
/// @dev Returns outcome count
/// @return Outcome count
function getOutcomeCount()
public
view
returns (uint8)
{
return uint8(outcomeTokens.length);
}
/// @dev Returns outcome tokens array
/// @return Outcome tokens
function getOutcomeTokens()
public
view
returns (OutcomeToken[] memory)
{
return outcomeTokens;
}
/// @dev Returns the amount of outcome tokens held by owner
/// @return Outcome token distribution
function getOutcomeTokenDistribution(address owner)
public
view
returns (uint[] memory outcomeTokenDistribution)
{
outcomeTokenDistribution = new uint[](outcomeTokens.length);
for (uint8 i = 0; i < outcomeTokenDistribution.length; i++)
outcomeTokenDistribution[i] = outcomeTokens[i].balanceOf(owner);
}
/// @dev Calculates and returns event hash
/// @return Event hash
function getEventHash() public view returns (bytes32);
/// @dev Exchanges sender's winning outcome tokens for collateral tokens
/// @return Sender's winnings
function redeemWinnings() public returns (uint);
}
|