@stabilitydao/host 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/npm.yml +19 -0
- package/.github/workflows/prettier.yml +25 -0
- package/.github/workflows/test.yml +29 -0
- package/.prettierignore +4 -0
- package/.prettierrc +1 -0
- package/LICENSE +674 -0
- package/README.md +35 -0
- package/jest.config.js +9 -0
- package/logo.png +0 -0
- package/out/index.js +30 -0
- package/package.json +28 -0
- package/src/activity/builder.ts +141 -0
- package/src/activity/index.ts +34 -0
- package/src/agents.ts +31 -0
- package/src/api.ts +51 -0
- package/src/assets.ts +1579 -0
- package/src/chains.ts +604 -0
- package/src/host.ts +1212 -0
- package/src/index.ts +36 -0
- package/src/storage/daoMetaData.ts +312 -0
- package/src/storage/daos.ts +306 -0
- package/src/tokenlist.json +1938 -0
- package/tests/assets.test.ts +61 -0
- package/tests/chains.test.ts +22 -0
- package/tests/host.test.ts +811 -0
- package/tsconfig.json +18 -0
|
@@ -0,0 +1,811 @@
|
|
|
1
|
+
import {
|
|
2
|
+
daos,
|
|
3
|
+
getDAOUnit,
|
|
4
|
+
Host,
|
|
5
|
+
UnitStatus,
|
|
6
|
+
UnitType,
|
|
7
|
+
daoMetaData,
|
|
8
|
+
Activity,
|
|
9
|
+
LifecyclePhase,
|
|
10
|
+
} from "../src";
|
|
11
|
+
import {
|
|
12
|
+
FundingType,
|
|
13
|
+
getDAOUnitMetaData,
|
|
14
|
+
IFunding,
|
|
15
|
+
IUnitMetaData,
|
|
16
|
+
IVesting,
|
|
17
|
+
} from "../src/host";
|
|
18
|
+
import { activities } from "../src/activity";
|
|
19
|
+
|
|
20
|
+
describe("testing Host", () => {
|
|
21
|
+
test("Lifecycle", () => {
|
|
22
|
+
// OS supports 3 EVM blockchains
|
|
23
|
+
// Ethereum
|
|
24
|
+
const os1 = new Host("1");
|
|
25
|
+
|
|
26
|
+
// Optimism
|
|
27
|
+
const os10 = new Host("10");
|
|
28
|
+
|
|
29
|
+
// BNB
|
|
30
|
+
const os56 = new Host("56");
|
|
31
|
+
|
|
32
|
+
// first DAO is Web3 developer studio team of aliens
|
|
33
|
+
// they are building and running DAO operating system
|
|
34
|
+
// SEED starts after 1 month
|
|
35
|
+
const daoAliens = os56.createDAO(
|
|
36
|
+
"Aliens Community",
|
|
37
|
+
"ALIENS",
|
|
38
|
+
[Activity.BUILDER, Activity.DEFI],
|
|
39
|
+
{
|
|
40
|
+
vePeriod: 365,
|
|
41
|
+
pvpFee: 100,
|
|
42
|
+
},
|
|
43
|
+
[_generateSeedFunding(os56)],
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
// todo other OS instances must see a symbol of new DAO
|
|
47
|
+
|
|
48
|
+
// 7 days later
|
|
49
|
+
os1.warpDays();
|
|
50
|
+
os10.warpDays();
|
|
51
|
+
os56.warpDays();
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
os56.changePhase(daoAliens.symbol);
|
|
55
|
+
} catch {}
|
|
56
|
+
|
|
57
|
+
// check what aliens need to do
|
|
58
|
+
const allTasks = os56.tasks(daoAliens.symbol);
|
|
59
|
+
expect(allTasks.length).toBeGreaterThanOrEqual(2);
|
|
60
|
+
|
|
61
|
+
// deployer drew token logotypes
|
|
62
|
+
os56.updateImages(daoAliens.symbol, {
|
|
63
|
+
seedToken: "/seedAliens.png",
|
|
64
|
+
token: "/aliens.png",
|
|
65
|
+
});
|
|
66
|
+
let currentTasks = os56.tasks(daoAliens.symbol);
|
|
67
|
+
expect(currentTasks.length).toBeLessThan(allTasks.length);
|
|
68
|
+
|
|
69
|
+
// units project
|
|
70
|
+
os56.updateUnits(
|
|
71
|
+
daoAliens.symbol,
|
|
72
|
+
[
|
|
73
|
+
{
|
|
74
|
+
unitId: "aliens:os",
|
|
75
|
+
chainIds: ["56"],
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
[
|
|
79
|
+
{
|
|
80
|
+
name: "DAO Factory",
|
|
81
|
+
status: UnitStatus.BUILDING,
|
|
82
|
+
type: UnitType.DEFI_PROTOCOL,
|
|
83
|
+
revenueShare: 100,
|
|
84
|
+
ui: [],
|
|
85
|
+
},
|
|
86
|
+
],
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
// registered socials
|
|
90
|
+
os56.updateSocials(daoAliens.symbol, ["https://a.aa/a", "https://b.bb/b"]);
|
|
91
|
+
currentTasks = os56.tasks(daoAliens.symbol);
|
|
92
|
+
expect(currentTasks.length).toEqual(0);
|
|
93
|
+
|
|
94
|
+
// fix funding
|
|
95
|
+
os56.updateFunding(daoAliens.symbol, {
|
|
96
|
+
...daoAliens.funding[0],
|
|
97
|
+
maxRaise: 90000,
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
try {
|
|
101
|
+
// phase cant be changed right now
|
|
102
|
+
os56.changePhase(daoAliens.symbol);
|
|
103
|
+
} catch {}
|
|
104
|
+
|
|
105
|
+
// 24 days later
|
|
106
|
+
os1.warpDays(24);
|
|
107
|
+
os10.warpDays(24);
|
|
108
|
+
os56.warpDays(24);
|
|
109
|
+
|
|
110
|
+
os56.changePhase(daoAliens.symbol);
|
|
111
|
+
|
|
112
|
+
// SEED started
|
|
113
|
+
expect(os56.getDAO(daoAliens.symbol).phase).toEqual(LifecyclePhase.SEED);
|
|
114
|
+
expect(os56.tasks(daoAliens.symbol).length).toBeGreaterThan(0);
|
|
115
|
+
|
|
116
|
+
// first seeder
|
|
117
|
+
os56.from = "0xseeder1";
|
|
118
|
+
os56.fund(daoAliens.symbol, 1000);
|
|
119
|
+
|
|
120
|
+
// since seed has funds first governance proposal can be created
|
|
121
|
+
let proposalId = os56.updateSocials(daoAliens.symbol, [
|
|
122
|
+
"https://a.aa/a",
|
|
123
|
+
"https://b.bb/b",
|
|
124
|
+
"https://c.c/c",
|
|
125
|
+
]) as string;
|
|
126
|
+
os56.receiveVotingResults(proposalId, true);
|
|
127
|
+
expect(os56.getDAO(daoAliens.symbol).socials.length).toEqual(3);
|
|
128
|
+
try {
|
|
129
|
+
os56.receiveVotingResults(proposalId, true);
|
|
130
|
+
} catch {}
|
|
131
|
+
try {
|
|
132
|
+
os56.receiveVotingResults(proposalId + "1", true);
|
|
133
|
+
} catch {}
|
|
134
|
+
|
|
135
|
+
// second seeder
|
|
136
|
+
os56.from = "0xseeder2";
|
|
137
|
+
os56.fund(daoAliens.symbol, 10000);
|
|
138
|
+
|
|
139
|
+
try {
|
|
140
|
+
os56.fund(daoAliens.symbol, 1000000);
|
|
141
|
+
} catch {}
|
|
142
|
+
|
|
143
|
+
try {
|
|
144
|
+
// phase cant be changed right now
|
|
145
|
+
os56.changePhase(daoAliens.symbol);
|
|
146
|
+
} catch {}
|
|
147
|
+
|
|
148
|
+
// 100 days later
|
|
149
|
+
os1.warpDays(100);
|
|
150
|
+
os10.warpDays(100);
|
|
151
|
+
os56.warpDays(100);
|
|
152
|
+
|
|
153
|
+
// DEVELOPMENT phase started (SEED succeed)
|
|
154
|
+
os56.changePhase(daoAliens.symbol);
|
|
155
|
+
expect(os56.getDAO(daoAliens.symbol).phase).toEqual(
|
|
156
|
+
LifecyclePhase.DEVELOPMENT,
|
|
157
|
+
);
|
|
158
|
+
expect(os56.tasks(daoAliens.symbol).length).toBeGreaterThan(0);
|
|
159
|
+
|
|
160
|
+
// fill TGE funding
|
|
161
|
+
try {
|
|
162
|
+
os56.getFundingIndex(daoAliens.symbol, FundingType.TGE);
|
|
163
|
+
} catch {}
|
|
164
|
+
proposalId = os56.updateFunding(
|
|
165
|
+
daoAliens.symbol,
|
|
166
|
+
_generateTGEFunding(os56),
|
|
167
|
+
) as string;
|
|
168
|
+
os56.receiveVotingResults(proposalId, true);
|
|
169
|
+
os56.getFundingIndex(daoAliens.symbol, FundingType.TGE); // not throws error
|
|
170
|
+
|
|
171
|
+
// fix units
|
|
172
|
+
proposalId = os56.updateUnits(
|
|
173
|
+
daoAliens.symbol,
|
|
174
|
+
[
|
|
175
|
+
{
|
|
176
|
+
...daoAliens.units[0],
|
|
177
|
+
},
|
|
178
|
+
],
|
|
179
|
+
[
|
|
180
|
+
{
|
|
181
|
+
...(daoAliens.unitsMetaData[0] as IUnitMetaData),
|
|
182
|
+
status: UnitStatus.LIVE,
|
|
183
|
+
ui: [
|
|
184
|
+
{
|
|
185
|
+
href: "https://mvp.ui",
|
|
186
|
+
title: "OS MVO",
|
|
187
|
+
},
|
|
188
|
+
],
|
|
189
|
+
},
|
|
190
|
+
],
|
|
191
|
+
) as string;
|
|
192
|
+
os56.receiveVotingResults(proposalId, true);
|
|
193
|
+
|
|
194
|
+
// add images
|
|
195
|
+
proposalId = os56.updateImages(daoAliens.symbol, {
|
|
196
|
+
seedToken: "/seedALIENS.png",
|
|
197
|
+
token: "/ALIENS.png",
|
|
198
|
+
tgeToken: "/tgeALIENS.png",
|
|
199
|
+
xToken: "/xALIENS.png",
|
|
200
|
+
daoToken: "/ALIENS_DAO.png",
|
|
201
|
+
}) as string;
|
|
202
|
+
os56.receiveVotingResults(proposalId, true);
|
|
203
|
+
|
|
204
|
+
// add vesting
|
|
205
|
+
|
|
206
|
+
proposalId = os56.updateVesting(daoAliens.symbol, [
|
|
207
|
+
_generateVesting(
|
|
208
|
+
"Development",
|
|
209
|
+
daoAliens.funding[
|
|
210
|
+
os56.getFundingIndex(daoAliens.symbol, FundingType.TGE)
|
|
211
|
+
].end as number,
|
|
212
|
+
),
|
|
213
|
+
]) as string;
|
|
214
|
+
os56.receiveVotingResults(proposalId, true);
|
|
215
|
+
|
|
216
|
+
// owner of DAO is seed token
|
|
217
|
+
expect(os56.getDaoOwner(daoAliens.symbol)).toBe(
|
|
218
|
+
daoAliens.deployments[os56.chainId].seedToken,
|
|
219
|
+
);
|
|
220
|
+
|
|
221
|
+
// try fund on not funding phase
|
|
222
|
+
try {
|
|
223
|
+
os56.fund(daoAliens.symbol, 100000000);
|
|
224
|
+
} catch {}
|
|
225
|
+
|
|
226
|
+
try {
|
|
227
|
+
// too early
|
|
228
|
+
os56.changePhase(daoAliens.symbol);
|
|
229
|
+
} catch {}
|
|
230
|
+
|
|
231
|
+
// 180 days later
|
|
232
|
+
os1.warpDays(180);
|
|
233
|
+
os10.warpDays(180);
|
|
234
|
+
os56.warpDays(180);
|
|
235
|
+
|
|
236
|
+
// TGE phase started (DEVELOPMENT done)
|
|
237
|
+
os56.changePhase(daoAliens.symbol);
|
|
238
|
+
expect(os56.getDAO(daoAliens.symbol).phase).toEqual(LifecyclePhase.TGE);
|
|
239
|
+
expect(os56.tasks(daoAliens.symbol).length).toBeGreaterThan(0);
|
|
240
|
+
|
|
241
|
+
// TGE funders
|
|
242
|
+
os56.from = "0xseeder1";
|
|
243
|
+
os56.fund(daoAliens.symbol, 10000);
|
|
244
|
+
os56.from = "0xseeder3";
|
|
245
|
+
os56.fund(daoAliens.symbol, 100000);
|
|
246
|
+
try {
|
|
247
|
+
os56.fund(daoAliens.symbol, 100000000);
|
|
248
|
+
} catch {}
|
|
249
|
+
|
|
250
|
+
try {
|
|
251
|
+
// too early
|
|
252
|
+
os56.changePhase(daoAliens.symbol);
|
|
253
|
+
} catch {}
|
|
254
|
+
|
|
255
|
+
// 8 days later
|
|
256
|
+
os1.warpDays(8);
|
|
257
|
+
os10.warpDays(8);
|
|
258
|
+
os56.warpDays(8);
|
|
259
|
+
|
|
260
|
+
// LIVE CLIFF
|
|
261
|
+
os56.changePhase(daoAliens.symbol);
|
|
262
|
+
expect(os56.getDAO(daoAliens.symbol).phase).toEqual(
|
|
263
|
+
LifecyclePhase.LIVE_CLIFF,
|
|
264
|
+
);
|
|
265
|
+
|
|
266
|
+
// owner of DAO is DAO token
|
|
267
|
+
expect(os56.getDaoOwner(daoAliens.symbol)).toBe(
|
|
268
|
+
daoAliens.deployments[os56.chainId].daoToken,
|
|
269
|
+
);
|
|
270
|
+
|
|
271
|
+
try {
|
|
272
|
+
// too early
|
|
273
|
+
os56.changePhase(daoAliens.symbol);
|
|
274
|
+
} catch {}
|
|
275
|
+
|
|
276
|
+
// 200 days later
|
|
277
|
+
os1.warpDays(200);
|
|
278
|
+
os10.warpDays(200);
|
|
279
|
+
os56.warpDays(200);
|
|
280
|
+
|
|
281
|
+
// LIVE_VESTING
|
|
282
|
+
os56.changePhase(daoAliens.symbol);
|
|
283
|
+
expect(os56.getDAO(daoAliens.symbol).phase).toEqual(
|
|
284
|
+
LifecyclePhase.LIVE_VESTING,
|
|
285
|
+
);
|
|
286
|
+
os56.tasks(daoAliens.symbol);
|
|
287
|
+
|
|
288
|
+
try {
|
|
289
|
+
// too early
|
|
290
|
+
os56.changePhase(daoAliens.symbol);
|
|
291
|
+
} catch {}
|
|
292
|
+
|
|
293
|
+
// 4000 days later
|
|
294
|
+
os1.warpDays(4000);
|
|
295
|
+
os10.warpDays(4000);
|
|
296
|
+
os56.warpDays(4000);
|
|
297
|
+
|
|
298
|
+
// LIVE
|
|
299
|
+
os56.changePhase(daoAliens.symbol);
|
|
300
|
+
expect(os56.getDAO(daoAliens.symbol).phase).toEqual(LifecyclePhase.LIVE);
|
|
301
|
+
os56.tasks(daoAliens.symbol);
|
|
302
|
+
|
|
303
|
+
// try update fundings for coverage
|
|
304
|
+
try {
|
|
305
|
+
os56.updateFunding(
|
|
306
|
+
daoAliens.symbol,
|
|
307
|
+
_generateSeedFunding(os1, 7 * 86400),
|
|
308
|
+
);
|
|
309
|
+
} catch {}
|
|
310
|
+
try {
|
|
311
|
+
os56.updateFunding(daoAliens.symbol, _generateTGEFunding(os1, 7 * 86400));
|
|
312
|
+
} catch {}
|
|
313
|
+
try {
|
|
314
|
+
os56.updateVesting(daoAliens.symbol, [
|
|
315
|
+
_generateVesting(
|
|
316
|
+
"Development",
|
|
317
|
+
daoAliens.funding[
|
|
318
|
+
os56.getFundingIndex(daoAliens.symbol, FundingType.TGE)
|
|
319
|
+
].end as number,
|
|
320
|
+
),
|
|
321
|
+
]);
|
|
322
|
+
} catch {}
|
|
323
|
+
|
|
324
|
+
const roadmap = os56.roadmap(daoAliens.symbol);
|
|
325
|
+
expect(roadmap.length).toBeGreaterThanOrEqual(6);
|
|
326
|
+
//console.log(roadmap)
|
|
327
|
+
|
|
328
|
+
// try change last phase
|
|
329
|
+
try {
|
|
330
|
+
// 4000 days later
|
|
331
|
+
os1.warpDays(4000);
|
|
332
|
+
os10.warpDays(4000);
|
|
333
|
+
os56.warpDays(4000);
|
|
334
|
+
os56.changePhase(daoAliens.symbol);
|
|
335
|
+
} catch {}
|
|
336
|
+
|
|
337
|
+
// second DAO are APES syndicate
|
|
338
|
+
// they cant build but need their own DeFi lending protocol
|
|
339
|
+
// they do many errors
|
|
340
|
+
const daoApes = os1.createDAO(
|
|
341
|
+
"Apes Syndicate",
|
|
342
|
+
"APES",
|
|
343
|
+
[Activity.DEFI],
|
|
344
|
+
{
|
|
345
|
+
vePeriod: 30,
|
|
346
|
+
pvpFee: 90,
|
|
347
|
+
},
|
|
348
|
+
[_generateSeedFunding(os1, 7 * 86400)],
|
|
349
|
+
);
|
|
350
|
+
|
|
351
|
+
// todo other OS instances must see a symbol of new DAO
|
|
352
|
+
|
|
353
|
+
os1.updateImages(daoApes.symbol, {
|
|
354
|
+
seedToken: "/seedApes.png",
|
|
355
|
+
token: "/apes.png",
|
|
356
|
+
});
|
|
357
|
+
os1.updateUnits(
|
|
358
|
+
daoApes.symbol,
|
|
359
|
+
[
|
|
360
|
+
{
|
|
361
|
+
unitId: "aliens:os",
|
|
362
|
+
chainIds: ["1"],
|
|
363
|
+
},
|
|
364
|
+
],
|
|
365
|
+
[
|
|
366
|
+
{
|
|
367
|
+
name: "DAO Factory",
|
|
368
|
+
status: UnitStatus.BUILDING,
|
|
369
|
+
type: UnitType.DEFI_PROTOCOL,
|
|
370
|
+
revenueShare: 100,
|
|
371
|
+
ui: [],
|
|
372
|
+
},
|
|
373
|
+
],
|
|
374
|
+
);
|
|
375
|
+
os1.updateSocials(daoApes.symbol, ["https://apes.aa", "https://apes.bb"]);
|
|
376
|
+
os1.updateVesting(daoApes.symbol, [
|
|
377
|
+
_generateVesting(
|
|
378
|
+
"Development",
|
|
379
|
+
daoAliens.funding[os1.getFundingIndex(daoApes.symbol, FundingType.SEED)]
|
|
380
|
+
.end as number,
|
|
381
|
+
),
|
|
382
|
+
]);
|
|
383
|
+
|
|
384
|
+
// apes forgot they created DRAFT
|
|
385
|
+
// 15 days later
|
|
386
|
+
os1.warpDays(15);
|
|
387
|
+
os10.warpDays(15);
|
|
388
|
+
os56.warpDays(15);
|
|
389
|
+
|
|
390
|
+
try {
|
|
391
|
+
// too late
|
|
392
|
+
os1.changePhase(daoApes.symbol);
|
|
393
|
+
} catch {}
|
|
394
|
+
|
|
395
|
+
os1.updateFunding(daoApes.symbol, _generateSeedFunding(os1, 7 * 86400));
|
|
396
|
+
|
|
397
|
+
// 7 days later
|
|
398
|
+
os1.warpDays();
|
|
399
|
+
os10.warpDays();
|
|
400
|
+
os56.warpDays();
|
|
401
|
+
|
|
402
|
+
os1.changePhase(daoApes.symbol);
|
|
403
|
+
|
|
404
|
+
// fund small amount
|
|
405
|
+
os1.from = "0xseeder1";
|
|
406
|
+
os1.fund(daoApes.symbol, 1000);
|
|
407
|
+
|
|
408
|
+
// 127 days later
|
|
409
|
+
os1.warpDays(127);
|
|
410
|
+
os10.warpDays(127);
|
|
411
|
+
os56.warpDays(127);
|
|
412
|
+
|
|
413
|
+
os1.changePhase(daoApes.symbol);
|
|
414
|
+
expect(os1.getDAO(daoApes.symbol).phase).toEqual(
|
|
415
|
+
LifecyclePhase.SEED_FAILED,
|
|
416
|
+
);
|
|
417
|
+
|
|
418
|
+
// third DAO are Machines Cartel
|
|
419
|
+
const daoMachines = os10.createDAO(
|
|
420
|
+
"Machines Cartel",
|
|
421
|
+
"MACHINE",
|
|
422
|
+
[Activity.MEV],
|
|
423
|
+
{
|
|
424
|
+
vePeriod: 14,
|
|
425
|
+
pvpFee: 99,
|
|
426
|
+
},
|
|
427
|
+
[_generateSeedFunding(os10, 7 * 86400), _generateTGEFunding(os10)],
|
|
428
|
+
);
|
|
429
|
+
|
|
430
|
+
os10.updateImages(daoMachines.symbol, {
|
|
431
|
+
seedToken: "/seedMACHINE.png",
|
|
432
|
+
token: "/MACHINE.png",
|
|
433
|
+
tgeToken: "/saleMACHINE.png",
|
|
434
|
+
xToken: "/xMACHINE.png",
|
|
435
|
+
daoToken: "/MACHINE_DAO.png",
|
|
436
|
+
});
|
|
437
|
+
os10.updateUnits(
|
|
438
|
+
daoMachines.symbol,
|
|
439
|
+
[
|
|
440
|
+
{
|
|
441
|
+
unitId: "MACHINES:MEVBOT",
|
|
442
|
+
chainIds: ["10"],
|
|
443
|
+
},
|
|
444
|
+
],
|
|
445
|
+
[
|
|
446
|
+
{
|
|
447
|
+
name: "MEV searcher",
|
|
448
|
+
status: UnitStatus.LIVE,
|
|
449
|
+
type: UnitType.MEV_SEARCHER,
|
|
450
|
+
revenueShare: 100,
|
|
451
|
+
ui: [],
|
|
452
|
+
api: [],
|
|
453
|
+
},
|
|
454
|
+
],
|
|
455
|
+
);
|
|
456
|
+
os10.updateSocials(daoMachines.symbol, [
|
|
457
|
+
"https://apes.aa",
|
|
458
|
+
"https://apes.bb",
|
|
459
|
+
]);
|
|
460
|
+
os10.updateVesting(daoMachines.symbol, [
|
|
461
|
+
_generateVesting(
|
|
462
|
+
"Development",
|
|
463
|
+
daoMachines.funding[
|
|
464
|
+
os10.getFundingIndex(daoMachines.symbol, FundingType.SEED)
|
|
465
|
+
].end as number,
|
|
466
|
+
),
|
|
467
|
+
]);
|
|
468
|
+
|
|
469
|
+
// 7 days later
|
|
470
|
+
os1.warpDays();
|
|
471
|
+
os10.warpDays();
|
|
472
|
+
os56.warpDays();
|
|
473
|
+
|
|
474
|
+
os10.changePhase(daoMachines.symbol);
|
|
475
|
+
|
|
476
|
+
// fund enough amount
|
|
477
|
+
os10.from = "0xseeder1";
|
|
478
|
+
os10.fund(daoMachines.symbol, 50000);
|
|
479
|
+
|
|
480
|
+
// 127 days later
|
|
481
|
+
os1.warpDays(127);
|
|
482
|
+
os10.warpDays(127);
|
|
483
|
+
os56.warpDays(127);
|
|
484
|
+
|
|
485
|
+
os10.changePhase(daoMachines.symbol);
|
|
486
|
+
|
|
487
|
+
// now DEVELOPMENT
|
|
488
|
+
|
|
489
|
+
// 180 days later
|
|
490
|
+
os1.warpDays(180);
|
|
491
|
+
os10.warpDays(180);
|
|
492
|
+
os56.warpDays(180);
|
|
493
|
+
|
|
494
|
+
os10.changePhase(daoMachines.symbol);
|
|
495
|
+
|
|
496
|
+
// now TGE
|
|
497
|
+
|
|
498
|
+
// 180 days later
|
|
499
|
+
os1.warpDays(180);
|
|
500
|
+
os10.warpDays(180);
|
|
501
|
+
os56.warpDays(180);
|
|
502
|
+
|
|
503
|
+
// TGE FAILED
|
|
504
|
+
os10.changePhase(daoMachines.symbol);
|
|
505
|
+
|
|
506
|
+
expect(os10.getDAO(daoMachines.symbol).phase).toEqual(
|
|
507
|
+
LifecyclePhase.DEVELOPMENT,
|
|
508
|
+
);
|
|
509
|
+
|
|
510
|
+
// rejected proposal coverage
|
|
511
|
+
proposalId = os10.updateSocials(daoMachines.symbol, [
|
|
512
|
+
"https://t.me/stabilitydao1",
|
|
513
|
+
]) as string;
|
|
514
|
+
os10.receiveVotingResults(proposalId as string, false);
|
|
515
|
+
});
|
|
516
|
+
|
|
517
|
+
test("launch", () => {
|
|
518
|
+
const os = new Host("146");
|
|
519
|
+
os.addLiveDAO(daos[1]);
|
|
520
|
+
expect(Object.keys(os.daos).length).toBe(1);
|
|
521
|
+
expect(
|
|
522
|
+
getDAOUnit(daos, daos[1].symbol, daos[1].units[1].unitId)?.unitId,
|
|
523
|
+
).toBe("stability:stabilityFarm");
|
|
524
|
+
expect(
|
|
525
|
+
getDAOUnitMetaData(daos, daos[1].symbol, daos[1].units[1].unitId)?.name,
|
|
526
|
+
).toBe("VaaS");
|
|
527
|
+
|
|
528
|
+
expect(os.getDAOMetaData(daoMetaData, daos[1].symbol));
|
|
529
|
+
const roadmap = os.roadmap(daos[1].symbol);
|
|
530
|
+
expect(roadmap.length).toBe(4);
|
|
531
|
+
//console.log(roadmap)
|
|
532
|
+
});
|
|
533
|
+
|
|
534
|
+
test("create DAO", () => {
|
|
535
|
+
const os = new Host("1");
|
|
536
|
+
const dao = _createDAO(os);
|
|
537
|
+
expect(dao.name).toBe("SpaceSwap");
|
|
538
|
+
expect(os.events.length).toBe(1);
|
|
539
|
+
expect(os.getDAOMetaData(daoMetaData, dao.symbol));
|
|
540
|
+
|
|
541
|
+
const funding: IFunding[] = [
|
|
542
|
+
{
|
|
543
|
+
type: FundingType.SEED,
|
|
544
|
+
start: 1800000000,
|
|
545
|
+
end: 1805000000,
|
|
546
|
+
minRaise: 20000,
|
|
547
|
+
maxRaise: 1000000,
|
|
548
|
+
raised: 0,
|
|
549
|
+
},
|
|
550
|
+
];
|
|
551
|
+
|
|
552
|
+
// bad name length
|
|
553
|
+
try {
|
|
554
|
+
os.createDAO(
|
|
555
|
+
"SpaceSwap_000000000000000000",
|
|
556
|
+
"SPACE",
|
|
557
|
+
[Activity.DEFI],
|
|
558
|
+
{
|
|
559
|
+
vePeriod: 365,
|
|
560
|
+
pvpFee: 90,
|
|
561
|
+
},
|
|
562
|
+
funding,
|
|
563
|
+
);
|
|
564
|
+
expect(0).toBe(1);
|
|
565
|
+
} catch (error: Error | unknown) {
|
|
566
|
+
expect((error as Error).message).toBe("NameLength(28)");
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
// bad symbol length
|
|
570
|
+
try {
|
|
571
|
+
os.createDAO(
|
|
572
|
+
"SpaceSwap",
|
|
573
|
+
"SPACESWAP",
|
|
574
|
+
[Activity.DEFI],
|
|
575
|
+
{
|
|
576
|
+
vePeriod: 365,
|
|
577
|
+
pvpFee: 90,
|
|
578
|
+
},
|
|
579
|
+
funding,
|
|
580
|
+
);
|
|
581
|
+
expect(0).toBe(1);
|
|
582
|
+
} catch (error: Error | unknown) {
|
|
583
|
+
expect((error as Error).message).toBe("SymbolLength(9)");
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
// not unique symbol
|
|
587
|
+
try {
|
|
588
|
+
os.createDAO(
|
|
589
|
+
"SpaceSwap",
|
|
590
|
+
"SPACE",
|
|
591
|
+
[Activity.DEFI],
|
|
592
|
+
{
|
|
593
|
+
vePeriod: 365,
|
|
594
|
+
pvpFee: 90,
|
|
595
|
+
},
|
|
596
|
+
funding,
|
|
597
|
+
);
|
|
598
|
+
expect(0).toBe(1);
|
|
599
|
+
} catch (error: Error | unknown) {
|
|
600
|
+
expect((error as Error).message).toBe("SymbolNotUnique(SPACE)");
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
// bad vePeriod
|
|
604
|
+
try {
|
|
605
|
+
os.createDAO(
|
|
606
|
+
"SpaceSwap",
|
|
607
|
+
"SPACE1",
|
|
608
|
+
[Activity.DEFI],
|
|
609
|
+
{
|
|
610
|
+
vePeriod: 365 * 5,
|
|
611
|
+
pvpFee: 100,
|
|
612
|
+
},
|
|
613
|
+
funding,
|
|
614
|
+
);
|
|
615
|
+
expect(0).toBe(1);
|
|
616
|
+
} catch (error: Error | unknown) {
|
|
617
|
+
expect((error as Error).message).toBe("VePeriod(1825)");
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
// bad pvpFee
|
|
621
|
+
try {
|
|
622
|
+
os.createDAO(
|
|
623
|
+
"SpaceSwap",
|
|
624
|
+
"SPACE1",
|
|
625
|
+
[Activity.DEFI],
|
|
626
|
+
{
|
|
627
|
+
vePeriod: 365,
|
|
628
|
+
pvpFee: 101,
|
|
629
|
+
},
|
|
630
|
+
funding,
|
|
631
|
+
);
|
|
632
|
+
expect(0).toBe(1);
|
|
633
|
+
} catch (error: Error | unknown) {
|
|
634
|
+
expect((error as Error).message).toBe("PvPFee(101)");
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
// no funding
|
|
638
|
+
try {
|
|
639
|
+
os.createDAO(
|
|
640
|
+
"SpaceSwap",
|
|
641
|
+
"SPACE1",
|
|
642
|
+
[Activity.DEFI],
|
|
643
|
+
{
|
|
644
|
+
vePeriod: 365,
|
|
645
|
+
pvpFee: 90,
|
|
646
|
+
},
|
|
647
|
+
[],
|
|
648
|
+
);
|
|
649
|
+
expect(0).toBe(1);
|
|
650
|
+
} catch (error: Error | unknown) {
|
|
651
|
+
expect((error as Error).message).toBe("NeedFunding");
|
|
652
|
+
}
|
|
653
|
+
});
|
|
654
|
+
|
|
655
|
+
test("update DAO images", () => {
|
|
656
|
+
const os = new Host("1");
|
|
657
|
+
const dao = _createDAO(os);
|
|
658
|
+
|
|
659
|
+
os.updateImages(dao.symbol, {
|
|
660
|
+
seedToken: "/img.png",
|
|
661
|
+
});
|
|
662
|
+
|
|
663
|
+
// force phase change
|
|
664
|
+
os.daos[Object.keys(os.daos)[0]].deployments = {
|
|
665
|
+
"1": {
|
|
666
|
+
seedToken: "0x1",
|
|
667
|
+
},
|
|
668
|
+
};
|
|
669
|
+
os.daos[Object.keys(os.daos)[0]].phase = LifecyclePhase.SEED;
|
|
670
|
+
os.from = "0x1";
|
|
671
|
+
os.updateImages(dao.symbol, {
|
|
672
|
+
seedToken: "/img.png",
|
|
673
|
+
});
|
|
674
|
+
});
|
|
675
|
+
|
|
676
|
+
test("update DAO socials", () => {
|
|
677
|
+
const os = new Host("146");
|
|
678
|
+
os.addLiveDAO(daos[1]);
|
|
679
|
+
|
|
680
|
+
os.from = "randomUserAddress1";
|
|
681
|
+
const dao = _createDAO(os);
|
|
682
|
+
os.from = "randomUserAddress2";
|
|
683
|
+
try {
|
|
684
|
+
os.updateSocials(dao.symbol, ["https://t.me/stabilitydao"]);
|
|
685
|
+
expect(false).toBe(true);
|
|
686
|
+
} catch {}
|
|
687
|
+
|
|
688
|
+
os.from = "randomUserAddress1";
|
|
689
|
+
os.updateSocials(dao.symbol, ["https://t.me/stabilitydao"]);
|
|
690
|
+
|
|
691
|
+
expect(os.getDAO(dao.symbol).socials.length).toBe(1);
|
|
692
|
+
expect(os.events.length).toBe(3);
|
|
693
|
+
|
|
694
|
+
try {
|
|
695
|
+
os.updateSocials(daos[1].symbol, ["https://t.me/stabilitydao"]);
|
|
696
|
+
} catch {}
|
|
697
|
+
os.from = daos[1].deployments["146"].daoToken as string;
|
|
698
|
+
os.chainId = "146";
|
|
699
|
+
let proposalId = os.updateSocials(daos[1].symbol, [
|
|
700
|
+
"https://t.me/stabilitydao1",
|
|
701
|
+
]);
|
|
702
|
+
os.receiveVotingResults(proposalId as string, true);
|
|
703
|
+
expect(os.getDAO(daos[1].symbol).socials[0]).toBe(
|
|
704
|
+
"https://t.me/stabilitydao1",
|
|
705
|
+
);
|
|
706
|
+
});
|
|
707
|
+
|
|
708
|
+
test("getDAOMetaData", () => {
|
|
709
|
+
const os = new Host("146");
|
|
710
|
+
os.addLiveDAO(daos[0]);
|
|
711
|
+
expect(
|
|
712
|
+
os.getDAOMetaData(daoMetaData, daos[0].symbol).builderActivity?.workers
|
|
713
|
+
.length,
|
|
714
|
+
).toBeGreaterThan(1);
|
|
715
|
+
});
|
|
716
|
+
|
|
717
|
+
test("get DAO", () => {
|
|
718
|
+
const os = new Host("1");
|
|
719
|
+
const dao = _createDAO(os);
|
|
720
|
+
os.getDAO(dao.symbol);
|
|
721
|
+
|
|
722
|
+
try {
|
|
723
|
+
os.getDAO("x");
|
|
724
|
+
expect(0).toBe(1);
|
|
725
|
+
} catch (error: Error | unknown) {
|
|
726
|
+
expect((error as Error).message).toBe("DAONotFound");
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
const roadmap = os.roadmap(dao.symbol);
|
|
730
|
+
expect(roadmap.length).toBeGreaterThanOrEqual(1);
|
|
731
|
+
//console.log(roadmap)
|
|
732
|
+
});
|
|
733
|
+
|
|
734
|
+
test("getters", () => {
|
|
735
|
+
// getTokensNaming
|
|
736
|
+
const naming = Host.getTokensNaming("Destiny", "DESTINY");
|
|
737
|
+
expect(naming.tokenSymbol).toBe("DESTINY");
|
|
738
|
+
expect(naming.tokenName).toBe("Destiny");
|
|
739
|
+
|
|
740
|
+
// isLiveDAO
|
|
741
|
+
expect(Host.isLiveDAO(LifecyclePhase.TGE)).toBe(false);
|
|
742
|
+
});
|
|
743
|
+
|
|
744
|
+
test("activities", () => {
|
|
745
|
+
const defiActivity = activities[Activity.DEFI];
|
|
746
|
+
expect(defiActivity.unitTypes[0]).toBe(UnitType.DEFI_PROTOCOL);
|
|
747
|
+
});
|
|
748
|
+
|
|
749
|
+
const _createDAO = (os: Host) => {
|
|
750
|
+
const funding = [_generateSeedFunding(os)];
|
|
751
|
+
return os.createDAO(
|
|
752
|
+
"SpaceSwap",
|
|
753
|
+
"SPACE",
|
|
754
|
+
[Activity.DEFI],
|
|
755
|
+
{
|
|
756
|
+
vePeriod: 365,
|
|
757
|
+
pvpFee: 90,
|
|
758
|
+
},
|
|
759
|
+
funding,
|
|
760
|
+
);
|
|
761
|
+
};
|
|
762
|
+
|
|
763
|
+
const _generateSeedFunding = (
|
|
764
|
+
os: Host,
|
|
765
|
+
after: number = 30 * 86400, // 1 month
|
|
766
|
+
duration: number = 3 * 30 * 86400, // 3 months
|
|
767
|
+
minRaise: number = 10000, // 10k USD
|
|
768
|
+
maxRaise: number = 100000, // 100k USD
|
|
769
|
+
): IFunding => {
|
|
770
|
+
return {
|
|
771
|
+
type: FundingType.SEED,
|
|
772
|
+
start: os.blockTimestamp + after,
|
|
773
|
+
end: os.blockTimestamp + after + duration,
|
|
774
|
+
minRaise,
|
|
775
|
+
maxRaise,
|
|
776
|
+
raised: 0,
|
|
777
|
+
};
|
|
778
|
+
};
|
|
779
|
+
|
|
780
|
+
const _generateTGEFunding = (
|
|
781
|
+
os: Host,
|
|
782
|
+
after: number = 6 * 30 * 86400, // 6 month
|
|
783
|
+
duration: number = 7 * 86400, // 7 days
|
|
784
|
+
minRaise: number = 100000, // 100k USD
|
|
785
|
+
maxRaise: number = 500000, // 500k USD
|
|
786
|
+
): IFunding => {
|
|
787
|
+
return {
|
|
788
|
+
type: FundingType.TGE,
|
|
789
|
+
start: os.blockTimestamp + after,
|
|
790
|
+
end: os.blockTimestamp + after + duration,
|
|
791
|
+
minRaise,
|
|
792
|
+
maxRaise,
|
|
793
|
+
raised: 0,
|
|
794
|
+
};
|
|
795
|
+
};
|
|
796
|
+
|
|
797
|
+
const _generateVesting = (
|
|
798
|
+
name: string,
|
|
799
|
+
tgeEnd: number,
|
|
800
|
+
cliff: number = 180 * 86400,
|
|
801
|
+
duration: number = 365 * 86400,
|
|
802
|
+
allocation: number = 100,
|
|
803
|
+
): IVesting => {
|
|
804
|
+
return {
|
|
805
|
+
name,
|
|
806
|
+
start: tgeEnd + cliff,
|
|
807
|
+
end: tgeEnd + cliff + duration,
|
|
808
|
+
allocation,
|
|
809
|
+
};
|
|
810
|
+
};
|
|
811
|
+
});
|