-
Notifications
You must be signed in to change notification settings - Fork 10
/
contract.se
204 lines (184 loc) · 8.57 KB
/
contract.se
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
data pools[]( recipient, name[1], name_len, condition[1], condition_len, deadline, voting_threshold, balance, vote_position, num_contributors, address_list[], pool[]( commitment, vote))
data owner
# Create a new Incentivization Pool
def create_pool(id, recipient, name: str, condition: str, max_duration, voting_threshold):
if self.pools[id].recipient:
return(0)
self.pools[id].recipient = recipient
save(self.pools[id].name[0], name, chars=len(name))
self.pools[id].name_len = len(name)
save(self.pools[id].condition[0], condition, chars=len(condition))
self.pools[id].condition_len = len(condition)
self.pools[id].deadline = block.timestamp + max_duration
self.pools[id].voting_threshold = voting_threshold
self.pools[id].balance = 0
self.pools[id].vote_position = 0
self.pools[id].num_contributors = 0
# TODO: remove after testing
self.owner = msg.sender
return(1)
def get_recipient(id):
return(self.pools[id].recipient)
def get_name(id):
with length = self.pools[id].name_len:
return(load(self.pools[id].name[0], chars=length): str)
def get_condition(id):
with length = self.pools[id].condition_len:
return(load(self.pools[id].condition[0], chars=length): str)
def get_deadline(id):
return(self.pools[id].deadline)
# Get the portion of voters that must agree that an event did, in fact, take
# place, for some pool.
def get_voting_threshold(id):
return(self.pools[id].voting_threshold)
# Retrieve the total amount of ether people have committed to the pool with
# this id.
def get_balance(id):
return(self.pools[id].balance)
# Get current swing of voting power.
def get_vote_position(id):
return(self.pools[id].vote_position)
def get_num_contributors(id):
return(self.pools[id].num_contributors)
# A participant commits funds to a pool.
def commit(id):
# pool doesn't exist
if !self.pools[id].recipient:
# do we have to refund here?
# send(msg.sender, msg.value)
return(0)
with sender = msg.sender:
with commitment = msg.value:
with prev_commitment = self.pools[id].pool[sender].commitment:
# This sender has already committed.
if prev_commitment != 0:
with vote = self.pools[id].pool[sender].vote:
self.pools[id].pool[sender].commitment += commitment
self.pools[id].vote_position += vote * commitment
if self.pools[id].vote_position <= self.pools[id].balance * self.pools[id].voting_threshold / 100 or self.pools[id].vote_position >= self.pools[id].balance * self.pools[id].voting_threshold / 100:
self.destroy(id)
return(1)
# new commitment
else:
with num_contributors = self.pools[id].num_contributors:
self.pools[id].address_list[num_contributors] = sender
self.pools[id].num_contributors += 1
self.pools[id].balance += commitment
self.pools[id].pool[sender].commitment = commitment
self.pools[id].pool[sender].vote = 0
return(1)
# A participant casts their vote in favor of an event happening and
# paying forward the commitments to the recipient.
def vote_yes(id):
if self.pools[id].recipient and self.pools[id].pool[msg.sender].commitment:
with commitment = self.pools[id].pool[msg.sender].commitment:
with vote = self.pools[id].pool[msg.sender].vote:
# No additional commitments added - typical case
if msg.value == 0:
self.pools[id].vote_position -= vote * commitment
self.pools[id].vote_position += commitment
self.pools[id].pool[msg.sender].vote = 1
else: # Additional commitments
self.pools[id].vote_position -= vote * commitment
self.pools[id].pool[msg.sender].commitment += msg.value
self.pools[id].vote_position += self.pools[id].pool[msg.sender].commitment
self.pools[id].pool[msg.sender].vote = 1
# reward
if self.pools[id].vote_position >= self.pools[id].balance * self.pools[id].voting_threshold / 100:
self.reward(id)
return(1)
else:
return(0)
# A participant casts their vote in favor of returning the funds from the
# pool to the participants.
def vote_no(id):
if self.pools[id].recipient and self.pools[id].pool[msg.sender].commitment:
with commitment = self.pools[id].pool[msg.sender].commitment:
with vote = self.pools[id].pool[msg.sender].vote:
# No additional commitments added - typical case
if msg.value == 0:
self.pools[id].vote_position -= vote * commitment
self.pools[id].vote_position -= commitment
self.pools[id].pool[msg.sender].vote = -1
else: # Additional commitments
self.pools[id].vote_position -= vote * commitment
self.pools[id].pool[msg.sender].commitment += msg.value
self.pools[id].vote_position -= self.pools[id].pool[msg.sender].commitment
self.pools[id].pool[msg.sender].vote = -1
# refund
if self.pools[id].vote_position <= self.pools[id].balance * self.pools[id].voting_threshold / -100:
self.refund(id)
return(1)
else:
return(0)
# A participant either changes their previously cast vote to a neutral
# abstain (potentially to keep the pool going), or this does nothing
# if they haven't already voted.
def abstain(id):
if self.pools[id].recipient and self.pools[id].pool[msg.sender].commitment:
with commitment = self.pools[id].pool[msg.sender].commitment:
with vote = self.pools[id].pool[msg.sender].vote:
# No additional commitments added - typical case
if msg.value == 0:
self.pools[id].vote_position -= vote * commitment
self.pools[id].pool[msg.sender].vote = 0
else: # Additional commitments
self.pools[id].vote_position -= vote * commitment
self.pools[id].pool[msg.sender].commitment += msg.value
self.pools[id].pool[msg.sender].vote = 0
return(1)
else:
return(0)
def reward(id):
if self.pools[id].vote_position >= self.pools[id].balance * self.pools[id].voting_threshold / 100:
send(self.pools[id].recipient, self.pools[id].balance)
# TODO: fix
# self.destroy(id)
return(1)
return(0)
def refund(id):
if self.pools[id].vote_position <= self.pools[id].balance * self.pools[id].voting_threshold / 100:
with num_contributors = self.pools[id].num_contributors:
i = 0
while i < num_contributors:
with addr = self.pools[id].address_list[i]:
with commitment = self.pools[id].pool[addr].commitment:
send(addr, commitment)
i += 1
# TODO: fix
# self.destroy(id)
return(1)
return(0)
# data pools[]( recipient, name[1], name_len, condition[1], condition_len,
# deadline, voting_threshold, balance, vote_position, num_contributors,
# address_list[], pool[]( commitment, vote))
def destroy(id):
if self.pools[id].vote_position <= self.pools[id].balance * self.pools[id].voting_threshold / 100 or self.pools[id].vote_position >= self.pools[id].balance * self.pools[id].voting_threshold / 100:
self.pools[id].recipient = 0
self.pools[id].name[0] = 0
self.pools[id].name_len = 0
self.pools[id].condition[0] = 0
self.pools[id].condition_len = 0
self.pools[id].deadline = 0
self.pools[id].voting_threshold = 0
self.pools[id].balance = 0
self.pools[id].vote_position = 0
c = self.pools[id].num_contributors
self.pools[id].num_contributors = 0
i = 0
while i < c:
addr = self.pools[id].address_list[addr]
self.pools[id].address_list[addr] = 0
self.pools[id].pool[addr].commitment = 0
self.pools[id].pool[addr].vote = 0
return(1)
return(0)
def check_deadline(id):
# TODO: implement deadline checking
return(0)
# TODO: remove after testing
def kill():
if self.owner == msg.sender:
suicide(self.owner)
else:
return(0)