-
Notifications
You must be signed in to change notification settings - Fork 0
/
crowdfunding.glow
63 lines (53 loc) · 2.51 KB
/
crowdfunding.glow
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
#lang glow
/* Here is how we can express the benchmark “crowdfunding” application, wherein pledgers pool money into a common account, the contents of which will be disbursed to the organizer if and only if a total target amount is reached before deadline. The hosts of the crowdfunding platform earn a small commission on the assets raised, which limits how much the organizer can take from the pledgers if he doesn’t reach the target. */
data Action = Pledge(TokenAmount) | Collect | Reclaim(TokenAmount);
let platformCommission amount = quotient(amount, 100);
// NB: This only works well because the ledger is linear.
// Can we make the linearity explicit in the typing?
// Also, for large merkleized trees,
// The Table.{add,get,remove} operations actually depend on publish! effects
// for the current participant to exhibit witnesses for the explored or summarized branches of the tree.
// For efficient refund on Ethereum, it could be an array / alist.
@interaction
let crowdfunding =
(Organizer: Participant, Platform: Participant,
target: TokenAmount, expirationTime : Timestamp) => {
require! expirationTime > currentTime();
let rec crowdfund = (ledger : Table(TokenAmount <- Participant),
totalPledged: TokenAmount) => {
assert! totalPledged == totalAmount(ledger);
choice {
| ForAllParticipant (NewPledger) {
@NewPledger amount =
input(["Enter next pledge"], TokenAmount);
publish! NewPledger -> Pledge(amount);
deposit! NewPledger -> amount;
require! currentTime() < expirationTime;
crowdfund(Table.add(ledger, NewPledger, amount),
totalPledged + amount);
| publish! Organizer -> Collect;
require! currentTime() >= expirationTime;
require! totalPledged >= target;
let commission = platformCommission(totalPledged);
withdraw! Platform <- commission;
withdraw! Organizer <- totalPledged - commission;
| ForAllParticipant(Pledger)
publish! Pledger -> Reclaim(amount);
require! currentTime() >= expirationTime;
require! totalPledged < target;
require! Table.get(ledger, Pledger) == amount;
withdraw! Pledger <- amount;
crowdfund(Table.remove(ledger, Pledger),
totalPledged - amount);
}
crowdfund({}, 0);
}
let awesome (
soething ! publish! ssumoting l
{
and something
( and something
and something
)
}
)