-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdao-hive-factory.pact
2916 lines (2725 loc) · 151 KB
/
dao-hive-factory.pact
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
(namespace (read-msg 'ns))
(module dao-hive-factory GOVERNANCE "Swarms.Finance DAO Swarm Factory"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Swarms.Finance ;
; __ ;
; DAO __/ \__ Factory ;
; __ / \__/ \ __ ;
; / \\ \__/ \__/ // \ ;
; \\ \_// / \__/ \ \\_/ // ;
; (')(||)- \__/ \__/ -(||)(') ;
; ''' \__/ ''' ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Creates and manages Kadena DAO Swarms
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;; CONSTANTS
(defconst ACCOUNT_ID_CHARSET CHARSET_LATIN1
"Allowed character set for Account IDs.")
(defconst NAME_MIN_LENGTH 3
"Minimum character length for names.")
(defconst NAME_MAX_LENGTH 40
"Maximum character length for names.")
(defconst DESCRIPTION_MIN_LENGTH 3
"Minimum character length for descriptions.")
(defconst DESCRIPTION_MAX_LENGTH 400
"Maximum character length for descriptions.")
(defconst COMMANDS ["WITHDRAW","SWAP","ADD_LIQUIDITY","REMOVE_LIQUIDITY","ADJUST_DAILY_LIMIT","ADJUST_THRESHOLD","ADJUST_VOTER_THRESHOLD","ADJUST_MIN_VOTETIME","ADD_MEMBER","REMOVE_MEMBER","AGAINST","ENABLE_PROPOSAL_CONTROL","ENABLE_WEIGHT","SET_WEIGHT","ADJUST_MEMBER_ROLE","EDIT_CHARTER"]
"Swarm Commands.")
(defconst ROLE_COMMANDS ["WITHDRAW","SWAP","ADD_LIQUIDITY","REMOVE_LIQUIDITY","ADJUST_DAILY_LIMIT","ADJUST_THRESHOLD","ADJUST_MIN_VOTETIME","ADD_MEMBER","REMOVE_MEMBER","ADJUST_MEMBER_ROLE"]
"Swarm Commands.")
;;;;; CAPABILITIES
(defcap GOVERNANCE ()
@doc "Verifies Contract Governance"
(enforce-keyset "free.admin-kadena-stake")
)
(defcap ACCOUNT_GUARD(account:string)
@doc "Verifies Account Existence"
(enforce-guard
(at "guard" (coin.details account))
)
)
(defcap CREATOR_GUARD(dao-id:string)
@doc "Verifies Swarm Creator Account"
(let
(
(dao-data (read daos-table dao-id ["dao_creator"]))
)
(enforce-guard
(at "guard" (coin.details (at "dao_creator" dao-data) ))
)
)
)
(defcap MEMBERS_GUARD(dao-id:string account:string)
@doc "Verifies account belongs to a dao member"
(let*
(
(memberships (read dao-membership-ids-table account))
(membership-ids (at "dao_ids" memberships))
)
(enforce (= (contains dao-id membership-ids) true) "Access not granted")
)
)
;For adding accounts
(defcap ADD_ACCOUNT
(dao_id:string)
true
)
;For adding accounts
(defcap CAN_ADD
(dao_id:string)
(compose-capability (ADD_ACCOUNT dao_id))
)
;For updating dao update messages
(defcap ADD_UPDATE
(dao_id:string)
true
)
;For updating dao update messages
(defcap CAN_UPDATE
(dao_id:string)
(compose-capability (ADD_UPDATE dao_id))
)
;For creating voting options
(defcap CAN_ADD_OPTION
(proposal_id:string)
(compose-capability (ADD_OPTION proposal_id))
)
;For creating voting options
(defcap ADD_OPTION
(proposal_id:string)
true
)
;For completing dao actions
(defcap COMPLETE_ACTION
()
true
)
;For completing dao actions
(defcap CAN_COMPLETE
(proposal_id:string dao_id:string)
(let*
(
(proposal-data (read dao-proposals-table proposal_id))
(proposal-dao (at "proposal_dao_id" proposal-data))
(proposal-completed (at "proposal_completed" proposal-data))
)
(enforce (= dao_id proposal-dao) "This proposal belongs to a different Swarm")
(enforce (= proposal-completed false) "This proposal has already been completed")
(compose-capability (COMPLETE_ACTION))
)
)
;DAO guards
(defcap PRIVATE_RESERVE
(id:string account:string)
true)
(defun enforce-private-reserve:bool
(id:string account:string)
(require-capability (PRIVATE_RESERVE id account)))
(defun create-pool-guard:guard
(id:string account:string)
(create-user-guard (enforce-private-reserve id account)))
(defun get-account-principal (id:string account:string)
(create-principal (create-pool-guard id account))
)
;;;;;;;;;; EVENTS ;;;;;;;;;;;;;;;;;;;;;;;;;;
(defcap DAO_HIVE_UPDATED (dao_id:string update_time:time)
@doc " Emitted when a DAO Swarm is updated "
@event true
)
;;;;;;;;;; SCHEMAS AND TABLES ;;;;;;;;;;;;;;
(defschema dao-schema
@doc " DAO Swarm schema "
dao_id:string
dao_name:string
dao_creator:string
dao_image:string
dao_long_description:string
dao_pool_count:integer
dao_proposal_count:integer
dao_messages_count:integer
dao_members_count:integer
dao_updates_count:integer
dao_daily_proposal_limit:integer
dao_threshold:decimal
dao_voter_threshold:decimal
dao_minimum_proposal_time:decimal
dao_members_locked:bool
dao_total_weight:decimal
dao_use_weight:bool
dao_all_can_propose:bool
dao_is_custom:bool
dao_chain:string
dao_active_chains:[string]
dao_roles:[string]
)
(defschema pool-record-schema
@doc " Pool record schema "
pool_id:string
pool_name:string
pool_use_weight:bool
pool_weight:decimal
pool_description:string
pool_account:string
pool_token:module{fungible-v2}
pool_tokenB:module{fungible-v2}
pool_lp:bool
pool_pair:string
pool_chain:string
pool_auto:bool
)
(defschema account-schema
@doc " Account schema "
account_id:string
account_name:string
account_dao_id:string
account_banned:bool
account_weight:decimal
account_can_propose:bool
account_count:integer
account_role:string
)
(defschema pool-action-schema
@doc " Pool action schema "
action:string
action_strings:[string]
action_integers:[integer]
action_decimals:[decimal]
)
(defschema pool-proposal-schema
@doc " Pool proposal schema "
proposal_id:string
proposal_count:integer
proposal_title:string
proposal_description:string
proposal_start_time:time
proposal_end_time:time
proposal_completed_time:time
proposal_completed_action:string
proposal_completed_consensus:decimal
proposal_completed_voter_consensus:decimal
proposal_dao_id:string
proposal_options_count:integer
proposal_creator:string
proposal_completed:bool
proposal_chain:string
)
(defschema vote-schema
@doc " Stores votes "
vote_count:integer
vote_option:object{pool-action-schema}
vote_description:string
vote_weight:decimal
)
(defschema dao-membership-schema
@doc " Stores account/dao memberships "
dao_ids:[string]
)
;Message schema
(defschema dao-message-schema
@doc " Message schema "
message_from:string
message_date:time
message:string
message_title:string
)
;User Vote Record Schema
(defschema user-vote-record
@doc " Vote record schema "
vote_account:string
vote_proposal:string
vote_time:time
vote_option:integer
)
;User Proposition Record Schema
(defschema user-proposition-record
@doc " Proposition record schema "
pr_account:string
pr_date:string
pr_proposition_count:integer
pr_propositions:[string]
)
(defschema dao-threshold-schema
action:string
threshold:decimal
count:integer
)
(defschema add-dao-threshold-schema
action:string
threshold:decimal
)
(defschema dao-role-schema
role_name:string
role_cant_vote:[string]
role_cant_propose:[string]
)
(defschema dao-link-schema
link_title:string
link_link:string
)
(defschema dao-charter-schema
charter:string
)
(defschema dao-links-schema
links:[object:{dao-link-schema}]
)
(defschema dao-custom-actions
actions:[string]
)
;;;;;;;;;;TABLES;;;;;;;;;;
(deftable daos-table:{dao-schema})
(deftable dao-membership-ids-table:{dao-membership-schema})
(deftable dao-messages-table:{dao-message-schema})
(deftable dao-updates-table:{dao-message-schema})
(deftable dao-accounts-table:{account-schema})
(deftable dao-pools-table:{pool-record-schema})
(deftable dao-proposals-table:{pool-proposal-schema})
(deftable dao-votes-table:{vote-schema})
(deftable user-vote-records:{user-vote-record})
(deftable user-proposition-records:{user-proposition-record})
(deftable dao-accounts-count-table:{account-schema})
(deftable dao-role-table:{dao-role-schema})
(deftable dao-thresholds-table:{dao-threshold-schema})
(deftable dao-charters-table:{dao-charter-schema})
(deftable dao-links-table:{dao-links-schema})
(deftable dao-actions-table:{dao-custom-actions})
;DAO COPY
(defschema dao-schema-xchain
@doc " DAO Multichain Copy schema "
dao_id:string
dao_name:string
dao_creator:string
dao_image:string
dao_long_description:string
dao_members_count:integer
dao_daily_proposal_limit:integer
dao_threshold:decimal
dao_voter_threshold:decimal
dao_minimum_proposal_time:decimal
dao_members_locked:bool
dao_total_weight:decimal
dao_use_weight:bool
dao_all_can_propose:bool
dao_is_custom:bool
dao_members:[object{account-schema}]
dao_roles:[string]
consensus_thresholds:[object{dao-threshold-schema}]
roles:[object{dao-role-schema}]
custom_actions:[string]
)
(defpact copy-dao-crosschain:string
( account_id:string dao_id:string target-chain:string )
@doc "Copy DAO to other chain"
(step
(with-capability (ACCOUNT_GUARD account_id)
(with-capability (MEMBERS_GUARD dao_id account_id)
(enforce (!= "" target-chain) "empty target-chain")
(enforce (!= (at 'chain-id (chain-data)) target-chain)
"cannot run cross-chain transfers to the same chain")
(let*
(
(dao-data (read daos-table dao_id))
(dao-custom-actions (at "actions" (read dao-actions-table dao_id)))
(dao-locked:bool (at "dao_members_locked" dao-data))
)
;Log new chain
(with-default-read daos-table dao_id
{ "dao_active_chains" : [] }
{ "dao_active_chains" := t-dao_active_chains}
(if (= (contains target-chain t-dao_active_chains) false)
(update daos-table dao_id
{
"dao_active_chains": (+ [target-chain] t-dao_active_chains )
}
)
true
)
)
(let
((crosschain-details:object{dao-schema-xchain}
{ "dao_id" : (at "dao_id" dao-data)
, "dao_name" : (at "dao_name" dao-data)
, "dao_image" : (at "dao_image" dao-data)
, "dao_long_description" : (at "dao_long_description" dao-data)
, "dao_members_count" : (at "dao_members_count" dao-data)
, "dao_daily_proposal_limit" : (at "dao_daily_proposal_limit" dao-data)
, "dao_threshold" : (at "dao_threshold" dao-data)
, "dao_voter_threshold" : (at "dao_voter_threshold" dao-data)
, "dao_minimum_proposal_time" : (at "dao_minimum_proposal_time" dao-data)
, "dao_members_locked" : (at "dao_members_locked" dao-data)
, "dao_total_weight" : (at "dao_total_weight" dao-data)
, "dao_use_weight" : (at "dao_use_weight" dao-data)
, "dao_is_custom" : (at "dao_is_custom" dao-data)
, "dao_all_can_propose" : (at "dao_all_can_propose" dao-data)
, "dao_creator" : (at "dao_creator" dao-data)
, "dao_members" : (get-all-dao-members dao_id)
, "dao_roles" : (at "dao_roles" dao-data)
, "consensus_thresholds" : (get-dao-thresholds dao_id)
, "roles" : (get-dao-roles dao_id)
, "custom_actions" : dao-custom-actions
}
))
(yield crosschain-details target-chain)
)
)
)
)
)
(step
(resume
{ "dao_id" := c_dao_id
, "dao_name" := c_dao_name
, "dao_image" := c_dao_image
, "dao_long_description" := c_dao_long_description
, "dao_members_count" := c_dao_members_count
, "dao_daily_proposal_limit" := c_dao_daily_proposal_limit
, "dao_threshold" := c_dao_threshold
, "dao_voter_threshold" := c_dao_voter_threshold
, "dao_minimum_proposal_time" := c_dao_minimum_proposal_time
, "dao_members_locked" := c_dao_members_locked
, "dao_total_weight" := c_dao_total_weight
, "dao_use_weight" := c_dao_use_weight
, "dao_is_custom" := c_dao_is_custom
, "dao_all_can_propose" := c_dao_all_can_propose
, "dao_creator" := c_dao_creator
, "dao_members" := c_dao_members
, "dao_roles" := c_dao_roles
, "consensus_thresholds" := c_consensus_thresholds
, "roles" := c_roles
, "custom_actions" := c_dao_custom_actions
}
(with-default-read daos-table c_dao_id
{ "dao_pool_count" : 0, "dao_proposal_count" : 0, "dao_updates_count" : 0, "dao_messages_count" : 0 }
{ "dao_pool_count" := c_dao_pool_count, "dao_proposal_count" := c_dao_proposal_count, "dao_updates_count" := c_dao_updates_count, "dao_messages_count" := c_dao_messages_count }
(write daos-table c_dao_id
{
"dao_id": c_dao_id,
"dao_name": c_dao_name,
"dao_creator": c_dao_creator,
"dao_image": c_dao_image,
"dao_long_description": c_dao_long_description,
"dao_members_count": c_dao_members_count,
"dao_threshold": c_dao_threshold,
"dao_voter_threshold": c_dao_voter_threshold,
"dao_daily_proposal_limit": c_dao_daily_proposal_limit,
"dao_pool_count": c_dao_pool_count,
"dao_proposal_count": c_dao_proposal_count,
"dao_updates_count": c_dao_updates_count,
"dao_messages_count": c_dao_messages_count,
"dao_minimum_proposal_time": c_dao_minimum_proposal_time,
"dao_members_locked": c_dao_members_locked,
"dao_total_weight": c_dao_total_weight,
"dao_use_weight": c_dao_use_weight,
"dao_all_can_propose": c_dao_all_can_propose,
"dao_is_custom": c_dao_is_custom,
"dao_chain": (at "chain-id" (chain-data)),
"dao_active_chains": [(at "chain-id" (chain-data))],
"dao_roles": c_dao_roles
}
)
(write dao-actions-table c_dao_id
{
"actions": c_dao_custom_actions
}
)
)
;Migrate thresholds + roles
(with-capability (CAN_UPDATE c_dao_id)
(map (copy-threshold c_dao_id) c_consensus_thresholds)
(map (validate-roles dao_id) c_roles)
)
;Migrate members
(with-capability (CAN_ADD c_dao_id)
(map (mass-copy) c_dao_members)
)
)
)
)
(defun mass-copy (new_account:object{account-schema})
@doc "Multichain copy helper function"
(bind new_account {
"account_id" := account_id,
"account_name" := account_name,
"account_dao_id" := account_dao_id,
"account_banned" := account_banned,
"account_weight" := account_weight,
"account_can_propose" := account_can_propose,
"account_count" := account_count,
"account_role" := account_role
}
(require-capability (ADD_ACCOUNT account_dao_id))
(with-default-read dao-membership-ids-table account_id
{ "dao_ids" : [] }
{ "dao_ids" := t-member-ids}
(if (= (contains account_dao_id t-member-ids) false)
(write dao-membership-ids-table account_id
{
"dao_ids": (+ [account_dao_id] t-member-ids )
}
)
true
)
)
;Copy account
(write dao-accounts-table (get-user-key account_id account_dao_id)
{
"account_id": account_id,
"account_name": account_name,
"account_dao_id": account_dao_id,
"account_banned": account_banned,
"account_weight": account_weight,
"account_can_propose": account_can_propose,
"account_count": account_count,
"account_role": account_role
}
)
(write dao-accounts-count-table (get-2-key account_count account_dao_id)
{
"account_id": account_id,
"account_name": account_name,
"account_dao_id": account_dao_id,
"account_banned": account_banned,
"account_weight": account_weight,
"account_can_propose": account_can_propose,
"account_count": account_count,
"account_role": account_role
}
)
)
)
;;///////////////////////
;;DAO CREATION
;;//////////////////////
;Creates a new DAO Swarm
;name: dao name (3-40 characters), string, ex "Test DAO"
;image: link to dao icon/image, string, ex "https://link"
;long_description: long description of dao, string (3-400 chars), ex "My awesome dao"
;min_proposal_time: minimum time in seconds proposals must run, decimal, ex 86400.00
;threshold: % of voters required to pass a vote, decimal < 1.0, 1.0 = 100%, ex 0.5
;members: list of member ids, add-account-schema, ex: [{"id":"k:stuart"}]
;locked: lock this dao from the start, a locked dao requires voting to edit the dao, bool, ex: false
;all_propose: can everyone propose or only the creator? ex: true
;use_weights: enable weight mode where voting power is based on deposits to the dao, ex: false
(defun create-dao
(
name:string
creator:string
image:string
long_description:string
min_proposal_time:decimal
threshold:decimal
voter_threshold:decimal
members:[object:{add-account-schema-create}]
locked:bool
all_propose:bool
use_weights:bool
is_custom:bool
consensus_thresholds:[object:{dao-threshold-schema}]
roles:[object:{dao-role-schema}]
custom_actions:[string]
)
@doc "Creates a new DAO Swarm"
(with-capability (ACCOUNT_GUARD creator)
;Enforce rules
(enforce-valid-name name)
(enforce-valid-description long_description)
(enforce (>= min_proposal_time 0.0) "Positive Minimum Proposal Time Only")
(enforce (<= threshold 1.0) "Threshold must be <= 1.0")
(enforce (>= threshold 0.0) "Positive Threshold Only")
(enforce (<= voter_threshold 1.0) "Threshold must be <= 1.0")
(enforce (>= voter_threshold 0.0) "Positive Threshold Only")
(enforce (>= (length members) 1) "Must add alteast 1 member when creating a DAO")
;Create dao
(let
(
(dao_id:string (create-account-key name creator))
)
;Validate thresholds & roles
(with-capability (CAN_UPDATE dao_id)
(map (validate-threshold dao_id) consensus_thresholds)
(map (copy-threshold dao_id) consensus_thresholds)
(map (validate-roles dao_id) roles)
)
;Insert DAO
(insert daos-table dao_id
{
"dao_id": dao_id,
"dao_name": name,
"dao_creator": creator,
"dao_image": image,
"dao_long_description": long_description,
"dao_members_count": 0,
"dao_threshold": threshold,
"dao_voter_threshold": voter_threshold,
"dao_daily_proposal_limit": 5,
"dao_pool_count": 0,
"dao_proposal_count": 0,
"dao_updates_count": 1,
"dao_messages_count": 1,
"dao_minimum_proposal_time": min_proposal_time,
"dao_members_locked": locked,
"dao_total_weight": 0.0,
"dao_use_weight": use_weights,
"dao_all_can_propose": all_propose,
"dao_is_custom": is_custom,
"dao_chain": (at "chain-id" (chain-data)),
"dao_active_chains": [(at "chain-id" (chain-data))],
"dao_roles": []
}
)
;Update roles
(with-capability (CAN_UPDATE dao_id)
(map (insert-roles dao_id) roles)
)
;Insert new dao update
(insert dao-updates-table (get-2-key 1 dao_id)
{
"message_from": "Swarm",
"message_date": (at "block-time" (chain-data)),
"message_title": "Genesis",
"message": (format "Created Swarm with ID {}" [dao_id])
}
)
;Insert new dao messages
(insert dao-messages-table (get-2-key 1 dao_id)
{
"message_from": "Swarm",
"message_date": (at "block-time" (chain-data)),
"message_title": "Genesis",
"message": (format "Created Swarm with ID {}" [dao_id])
}
)
;Insert custom actions
(insert dao-actions-table dao_id
{
"actions": custom_actions
}
)
;Add new members to dao
(with-capability (CAN_ADD dao_id)
(map (mass-adder dao_id false) members )
)
;Update creator with permissions
(update dao-accounts-table (get-user-key creator dao_id)
{
"account_can_propose": true
}
)
(update dao-accounts-count-table (get-2-key 0 dao_id)
{
"account_can_propose": true
}
)
;Return a message
(format "Created DAO Swarm: {}" [dao_id])
)
)
)
;Validates and copys roles
(defun validate-roles (dao_id:string role:object{dao-role-schema})
(require-capability (ADD_UPDATE dao_id))
(bind role {
"role_name" := role_name,
"role_cant_vote" := role_cant_vote:[string],
"role_cant_propose" := role_cant_propose:[string]
}
(write dao-role-table (get-user-key dao_id role_name)
{
"role_name": role_name,
"role_cant_vote": role_cant_vote,
"role_cant_propose": role_cant_propose
}
)
)
)
;Inserts roles
(defun insert-roles (dao_id:string role:object{dao-role-schema})
(require-capability (ADD_UPDATE dao_id))
(let
(
(dao_roles:[string] (at "dao_roles" (read daos-table dao_id)) )
)
(bind role {
"role_name" := role_name
}
(update daos-table dao_id
{
"dao_roles": (+ [role_name] dao_roles )
}
)
)
)
)
;Validates and initializes action thresholds
(defun validate-threshold (dao_id:string thresholds:object{dao-threshold-schema})
(require-capability (ADD_UPDATE dao_id))
(bind thresholds {
"action" := action,
"threshold" := threshold
}
(enforce (<= threshold 1.0) "Threshold must be <= 1.0")
(enforce (>= threshold 0.0) "Positive Threshold Only")
)
)
;Copys thresholds
(defun copy-threshold (dao_id:string thresholds:object{dao-threshold-schema})
(require-capability (ADD_UPDATE dao_id))
(bind thresholds {
"action" := action,
"threshold" := threshold,
"count" := count
}
(write dao-thresholds-table (get-user-key dao_id action)
{
"action": action,
"threshold": threshold,
"count": count
}
)
)
)
;Updates a specific action's threshold
(defun update-threshold (dao_id:string amount:decimal action:string)
(require-capability (ADD_UPDATE dao_id))
(with-default-read dao-thresholds-table (get-user-key dao_id action)
{ "count" : 0 }
{ "count" := t-count}
(write dao-thresholds-table (get-user-key dao_id action)
{
"action": action,
"threshold": amount,
"count": t-count
}
)
)
)
;;Locks a dao so it's not editable by the dao creator
(defun lock-dao
(account_id:string dao_id:string)
@doc " Locks a DAO "
(with-capability (ACCOUNT_GUARD account_id)
(with-capability (CREATOR_GUARD dao_id)
(update daos-table dao_id
{
"dao_members_locked": true
}
)
(with-capability (CAN_UPDATE dao_id)
(add-dao-update dao_id account_id "Swarm Locked" (format "Swarm Creator {} has given up their special permissions to edit the Swarm- The Swarm is now officially locked." [account_id]))
)
(format "Locked Swarm {}" [dao_id])
)
)
)
;Update dao info
(defun edit-dao-info
(account_id:string dao_id:string image:string long_description:string)
@doc " Update a DAO's info "
(with-capability (ACCOUNT_GUARD account_id)
(with-capability (MEMBERS_GUARD dao_id account_id)
(enforce-valid-description long_description)
(update daos-table dao_id
{
"dao_image": image,
"dao_long_description": long_description
}
)
(format "Update Swarm {}" [dao_id])
)
)
)
;Update dao links
(defun edit-dao-links
(account_id:string dao_id:string links:[object:{dao-link-schema}])
@doc " Update a DAO's links "
(with-capability (ACCOUNT_GUARD account_id)
(with-capability (MEMBERS_GUARD dao_id account_id)
(write dao-links-table dao_id
{
"links": links
}
)
(format "Update Swarm {} Links" [dao_id])
)
)
)
;;///////////////////////
;;DAO MEMBER ACCOUNTS
;;//////////////////////
;Object used for add multiple accounts at once
(defschema add-account-schema
@doc " Mass adder helper schema "
id:string
)
(defschema add-account-schema-create
@doc " Mass adder helper schema "
id:string
can_propose:bool
role:string
)
;Helper function to add multiple accounts at once when creating a DAO
(defun mass-adder (dao_id:string do_count:bool new_accounts:object{add-account-schema-create})
@doc " Adds multiple accounts to a DAO "
(bind new_accounts {
"id" := new_id,
"can_propose" := dao_can_propose,
"role" := role
}
(add-account dao_id new_id dao_can_propose role do_count)
)
)
(defun add-permissions (dao_id:string cant-vote-data:string)
(require-capability (ADD_UPDATE dao_id))
(let
(
(custom_actions:[string] (at "actions" (read dao-actions-table dao_id)))
)
(map (add-permissions2 dao_id cant-vote-data) COMMANDS)
(map (add-permissions2 dao_id cant-vote-data) custom_actions)
)
)
(defun add-permissions2 (dao_id:string command1:string command2:string)
(require-capability (ADD_UPDATE dao_id))
(if (!= command1 command2)
(with-default-read dao-thresholds-table (get-user-key dao_id command2)
{ "count" : 0 }
{ "count" := t-count}
(update dao-thresholds-table (get-user-key dao_id command2)
{
"count": (+ t-count 1)
}
)
)
true
)
)
(defun add-custom-permissions (dao_id:string command:string)
(require-capability (ADD_UPDATE dao_id))
(with-default-read dao-thresholds-table (get-user-key dao_id command)
{ "count" : 0 }
{ "count" := t-count}
(update dao-thresholds-table (get-user-key dao_id command)
{
"count": (+ t-count 1)
}
)
)
)
(defun remove-permissions (dao_id:string cant-vote-data:string)
(require-capability (ADD_UPDATE dao_id))
(map (remove-permissions2 dao_id cant-vote-data) COMMANDS)
)
(defun remove-permissions2 (dao_id:string command1:string command2:string)
(require-capability (ADD_UPDATE dao_id))
(if (!= command1 command2)
(with-default-read dao-thresholds-table (get-user-key dao_id command2)
{ "count" : 0 }
{ "count" := t-count}
(update dao-thresholds-table (get-user-key dao_id command2)
{
"count": (if (>= (- t-count 1) 0) (- t-count 1) 0)
}
)
)
true
)
)
;Adds account members to a dao - Permissioned
(defun add-account (dao_id:string new_account:string can_propose:bool role:string do_count:bool)
@doc " Adds a single account to a DAO "
(require-capability (ADD_ACCOUNT dao_id))
;Record DAO id to member
(with-default-read dao-membership-ids-table new_account
{ "dao_ids" : [] }
{ "dao_ids" := t-member-ids}
(if (= (contains new_account t-member-ids) false)
(write dao-membership-ids-table new_account
{
"dao_ids": (+ [dao_id] t-member-ids )
}
)
true
)
)
(if (= do_count true)
(let*
(
(role-cant-vote-data (at "role_cant_vote" (read dao-role-table (get-user-key dao_id role))))
)
(with-capability (CAN_UPDATE dao_id)
(map (add-permissions dao_id) role-cant-vote-data)
)
)
true
)
(with-default-read daos-table dao_id
{ "dao_updates_count" : 1, "dao_members_count" : 1, "dao_total_weight": 1.0 }
{ "dao_updates_count" := t-updates-count:integer, "dao_members_count" := t-member-count:integer, "dao_total_weight" := t-dao-total-weight}
;Post dao msg
(insert dao-updates-table (get-2-key (+ 1 t-updates-count) dao_id)
{
"message_from": "Swarm",
"message_date": (at "block-time" (chain-data)),
"message_title": "New Swarm Member",
"message": (format "New member {} has been added to the Swarm" [new_account])
}
)
;Insert account
(insert dao-accounts-table (get-user-key new_account dao_id)
{
"account_id": new_account,
"account_name": new_account,
"account_dao_id": dao_id,
"account_banned": false,
"account_weight": 1.0,
"account_can_propose": can_propose,
"account_count": t-member-count,
"account_role": role
}
)
;Insert account
(insert dao-accounts-count-table (get-2-key t-member-count dao_id)
{
"account_id": new_account,
"account_name": new_account,
"account_dao_id": dao_id,
"account_banned": false,
"account_weight": 1.0,
"account_can_propose": can_propose,
"account_count": t-member-count,
"account_role": role
}
)
;Update dao
(update daos-table dao_id
{
"dao_updates_count": (+ 1 t-updates-count),
"dao_members_count": (+ 1 t-member-count),
"dao_total_weight": (+ 1 t-dao-total-weight)
}
)
)
)
;Edit account name
(defun edit-account-info
(account_id:string dao_id:string new_id:string)
@doc " Edit user account name "
(with-capability (ACCOUNT_GUARD account_id)
(with-capability (MEMBERS_GUARD dao_id account_id)