@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.
@@ -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
+ });