-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.rsh
69 lines (58 loc) · 1.95 KB
/
index.rsh
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
'reach 0.1';
'use strict';
// FOMO Workshop generalized to last N winners
const NUM_OF_WINNERS = 1;
const CommonInterface = {
showOutcome: Fun([Array(Address, NUM_OF_WINNERS)], Null),
};
const FunderInterface = {
...CommonInterface,
getParams: Fun([], Object({
deadline: UInt, // relative deadline
ticketPrice: UInt,
})),
};
const BuyerInterface = {
...CommonInterface,
shouldBuyTicket: Fun([UInt], Bool),
showPurchase: Fun([Address], Null),
};
export const main = Reach.App(
{ },
[
Participant('Funder', FunderInterface), ParticipantClass('Buyer', BuyerInterface),
],
(Funder, Buyer) => {
const showOutcome = (winners) =>
each([Funder, Buyer], () => interact.showOutcome(winners));
Funder.only(() => {
const { ticketPrice, deadline } = declassify(interact.getParams()); });
Funder.publish(ticketPrice, deadline);
const initialWinners = Array.replicate(NUM_OF_WINNERS, Funder);
// Until deadline, allow buyers to buy ticket
const [ keepGoing, winners, ticketsSold ] =
parallelReduce([ true, initialWinners, 0 ])
.invariant(balance() == ticketsSold * ticketPrice)
.while(keepGoing)
.case(
Buyer,
() => ({
when: declassify(interact.shouldBuyTicket(ticketPrice)) }),
(_) => ticketPrice,
(_) => {
const buyer = this;
Buyer.only(() => interact.showPurchase(buyer));
const idx = ticketsSold % NUM_OF_WINNERS;
const newWinners =
Array.set(winners, idx, buyer);
return [ true, newWinners, ticketsSold + 1 ]; })
.timeout(relativeTime(deadline), () => {
Anybody.publish();
return [ false, winners, ticketsSold ]; });
transfer(balance() % NUM_OF_WINNERS).to(Funder);
const reward = balance() / NUM_OF_WINNERS;
winners.forEach(winner =>
transfer(reward).to(winner));
commit();
showOutcome(winners);
});