ICO
A real life ico process
This is the archetype version of the ICO process set up by BCDiploma and described at the following address:
1
archetype ico
2
3
constant symbol : string = "BCDT"
4
5
constant decimals : int = 18
6
7
(* contribution thresholds *)
8
variable min_contribution : tez = 1tz
9
variable max_contribution_silver : tez = 10tz
10
11
(* bcd token data *)
12
variable max_bcd_to_sell : tez = 100000000tz
13
variable exchange_rate_bcd_tez : int = 13000
14
15
(* round caps *)
16
variable soft_cap : tez = 1800tz
17
variable presales_cap : tez = 1800tz
18
variable round1_cap : tez = 3600tz
19
(* presales_cap + 1600 *)
20
21
(* Number tokens sent, eth raised, ... *)
22
variable nb_bcd_sold : tez = 0tz
23
variable nb_tez_raised : tez = 0tz
24
25
(* Roles *)
26
27
variable owner : role = @tz1XZ7s6uStC2hZVpPQhXgcdXPwxifByF3Ao
28
29
variable whitelister : role = @tz1Lc2qBKEWCBeDU8npG6zCeCqpmaegRi6Jg
30
31
variable reserve : role = @tz1bfVgcJC4ukaQSHUe1EbrUd5SekXeP9CWk
32
33
variable community : role = @tz1iawHeddgggn6P5r5jtq2wDRqcJVksGVSa
34
35
(* contributor *)
36
37
enum whitelist =
38
| Silver
39
| Gold
40
41
asset contributor identified by id {
42
id : address;
43
wlist : whitelist;
44
contrib : tez = 0tz;
45
}
46
47
enum gstate =
48
| Init initial (* ICO isn't started yet, initial state *)
49
| PresaleRunning (* Presale has started *)
50
| PresaleFinished (* Presale has ended *)
51
| Round1Running (* Round 1 has started *)
52
| Round1Finished (* Round 1 has ended *)
53
| Round2Running (* Round 2 has started *)
54
| Round2Finished (* Round 2 has ended *)
55
56
variable vstate : gstate = Init
57
58
function is_running () : bool {
59
return
60
match vstate with
61
| PresaleRunning | Round1Running | Round2Running -> true
62
| _ -> false
63
end
64
}
65
66
function get_rate () : rational {
67
var coeff : rational =
68
match vstate with
69
| PresaleRunning -> 1.2
70
| Round1Running -> 1.1
71
| _ -> 1
72
end;
73
return (coeff * exchange_rate_bcd_tez)
74
}
75
76
function get_remaining_tez_to_raise () : tez {
77
return
78
match vstate with
79
| PresaleRunning | PresaleFinished -> presales_cap - nb_tez_raised
80
| Round1Running | Round1Finished -> round1_cap - nb_tez_raised
81
| _ -> (
82
let remaining_bcd : tez = max_bcd_to_sell - nb_bcd_sold in
83
(1 / exchange_rate_bcd_tez) * remaining_bcd)
84
end
85
}
86
87
function transition_to_finished () : gstate {
88
return
89
match vstate with
90
| PresaleRunning -> PresaleFinished
91
| Round1Running -> Round1Finished
92
| Round1Finished -> Round2Running
93
| _ -> Round2Finished
94
end
95
}
96
97
entry contribute () {
98
99
require {
100
c1 : contributor.contains(caller);
101
c2 : is_running ();
102
c3 : transferred >= min_contribution;
103
c4 : (not (contributor[caller].wlist = Silver and transferred >= max_contribution_silver));
104
}
105
106
effect {
107
(* cap contribution to max_contrib if necessary *)
108
var lcontrib = transferred;
109
if contributor[caller].wlist = Silver
110
and contributor[caller].contrib + lcontrib >= max_contribution_silver
111
then lcontrib := max_contribution_silver - contributor[caller].contrib;
112
(* cap contribution to round cap if necessary *)
113
var remaining_tez : tez = get_remaining_tez_to_raise ();
114
if remaining_tez <= lcontrib
115
then (
116
lcontrib := remaining_tez;
117
vstate := transition_to_finished ()
118
);
119
(* convert contribution to nb of bcd tokens *)
120
var rate = get_rate ();
121
var nb_tokens : tez = rate * lcontrib;
122
(* update ico stats *)
123
nb_bcd_sold += nb_tokens;
124
nb_tez_raised += lcontrib;
125
(* update caller's contribution *)
126
contributor[caller].contrib += lcontrib;
127
(* syntaxic sugar for
128
contributor.update caller { contrib += contrib } *)
129
if lcontrib <= transferred
130
then transfer (transferred - lcontrib) to caller
131
}
132
}
133
134
(* the onlyonce extension specifies that withdraw action can be
135
executed only once, that is a contributor can withdraw only once. *)
136
137
entry withdraw () {
138
require {
139
c5 : vstate = Round2Finished;
140
c6 : nb_tez_raised <= soft_cap;
141
c7 : contributor[caller].contrib > 0tz;
142
}
143
144
effect {
145
transfer contributor[caller].contrib to caller;
146
(* do not forget this *)
147
contributor[caller].contrib := 0tz
148
}
149
}
150
Copied!
Last modified 1yr ago
Export as PDF
Copy link