@indigo-labs/indigo-sdk 0.1.7 → 0.1.9

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.
Files changed (89) hide show
  1. package/.github/workflows/ci.yml +62 -0
  2. package/.github/workflows/test.yml +44 -0
  3. package/.husky/pre-commit +1 -0
  4. package/.nvmrc +1 -0
  5. package/.prettierrc +6 -0
  6. package/dist/index.d.mts +19 -9
  7. package/dist/index.d.ts +19 -9
  8. package/dist/index.js +341 -315
  9. package/dist/index.mjs +92 -64
  10. package/eslint.config.mjs +36 -0
  11. package/package.json +2 -6
  12. package/src/contracts/cdp.ts +748 -0
  13. package/src/contracts/collector.ts +98 -0
  14. package/src/contracts/gov.ts +1 -0
  15. package/src/contracts/interest-oracle.ts +149 -0
  16. package/src/contracts/lrp.ts +308 -0
  17. package/src/contracts/one-shot.ts +67 -0
  18. package/src/contracts/stability-pool.ts +684 -0
  19. package/src/contracts/staking.ts +348 -0
  20. package/src/contracts/treasury.ts +112 -0
  21. package/src/helpers/asset-helpers.ts +57 -0
  22. package/src/helpers/helper-txs.ts +30 -0
  23. package/src/helpers/helpers.ts +38 -0
  24. package/src/helpers/indigo-helpers.ts +19 -0
  25. package/src/helpers/interest-oracle.ts +57 -0
  26. package/src/helpers/lucid-utils.ts +70 -0
  27. package/src/helpers/price-oracle-helpers.ts +36 -0
  28. package/src/helpers/stability-pool-helpers.ts +207 -0
  29. package/src/helpers/staking-helpers.ts +94 -0
  30. package/src/helpers/time-helpers.ts +4 -0
  31. package/src/helpers/value-helpers.ts +27 -0
  32. package/src/index.ts +34 -0
  33. package/src/scripts/always-fail-validator.ts +7 -0
  34. package/src/scripts/auth-token-policy.ts +23 -0
  35. package/src/scripts/cdp-creator-validator.ts +53 -0
  36. package/src/scripts/cdp-validator.ts +9 -0
  37. package/src/scripts/collector-validator.ts +8 -0
  38. package/src/scripts/execute-validator.ts +52 -0
  39. package/src/scripts/gov-validator.ts +44 -0
  40. package/src/scripts/iasset-policy.ts +22 -0
  41. package/src/scripts/interest-oracle-validator.ts +23 -0
  42. package/src/scripts/lrp-validator.ts +40 -0
  43. package/src/scripts/one-shot-policy.ts +62 -0
  44. package/src/scripts/poll-manager-validator.ts +52 -0
  45. package/src/scripts/poll-shard-validator.ts +47 -0
  46. package/src/scripts/price-oracle-validator.ts +26 -0
  47. package/src/scripts/stability-pool-validator.ts +60 -0
  48. package/src/scripts/staking-validator.ts +8 -0
  49. package/src/scripts/treasury-validator.ts +8 -0
  50. package/src/scripts/version-record-policy.ts +26 -0
  51. package/src/scripts/version-registry.ts +15 -0
  52. package/src/types/generic.ts +106 -0
  53. package/src/types/indigo/cdp-creator.ts +46 -0
  54. package/src/types/indigo/cdp.ts +88 -0
  55. package/src/types/indigo/execute.ts +21 -0
  56. package/src/types/indigo/gov.ts +51 -0
  57. package/src/types/indigo/interest-oracle.ts +55 -0
  58. package/src/types/indigo/lrp.ts +59 -0
  59. package/src/types/indigo/poll-manager.ts +21 -0
  60. package/src/types/indigo/poll-shard.ts +16 -0
  61. package/src/types/indigo/price-oracle.ts +38 -0
  62. package/src/types/indigo/stability-pool.ts +233 -0
  63. package/src/types/indigo/staking.ts +99 -0
  64. package/src/types/indigo/version-record.ts +17 -0
  65. package/src/types/on-chain-decimal.ts +23 -0
  66. package/src/types/one-shot.ts +22 -0
  67. package/src/types/system-params.ts +256 -0
  68. package/tests/data/system-params.json +1012 -0
  69. package/tests/datums.test.ts +286 -0
  70. package/tests/endpoints/initialize.ts +1013 -0
  71. package/tests/hash-checks.test.ts +80 -0
  72. package/tests/indigo-test-helpers.ts +115 -0
  73. package/tests/initialize.test.ts +27 -0
  74. package/tests/interest-calculations.test.ts +120 -0
  75. package/tests/interest-oracle.test.ts +90 -0
  76. package/tests/lrp.test.ts +769 -0
  77. package/tests/queries/governance-queries.ts +31 -0
  78. package/tests/queries/iasset-queries.ts +39 -0
  79. package/tests/queries/interest-oracle-queries.ts +13 -0
  80. package/tests/queries/lrp-queries.ts +39 -0
  81. package/tests/queries/price-oracle-queries.ts +27 -0
  82. package/tests/queries/stability-pool-queries.ts +75 -0
  83. package/tests/queries/staking-queries.ts +43 -0
  84. package/tests/stability-pool.test.ts +387 -0
  85. package/tests/staking.test.ts +105 -0
  86. package/tests/test-helpers.ts +38 -0
  87. package/tsconfig.build.json +4 -0
  88. package/tsconfig.json +17 -0
  89. package/vitest.config.ts +9 -0
@@ -0,0 +1,1013 @@
1
+ import {
2
+ Constr,
3
+ credentialToAddress,
4
+ Data,
5
+ fromText,
6
+ LucidEvolution,
7
+ mintingPolicyToId,
8
+ PolicyId,
9
+ SpendingValidator,
10
+ validatorToAddress,
11
+ validatorToScriptHash,
12
+ } from '@lucid-evolution/lucid';
13
+ import {
14
+ addrDetails,
15
+ AssetClass,
16
+ CDPContract,
17
+ CDPCreatorParamsSP,
18
+ CdpParams,
19
+ CollectorContract,
20
+ CollectorParams,
21
+ ExecuteParamsSP,
22
+ GovDatum,
23
+ GovParamsSP,
24
+ IAssetContent,
25
+ Input,
26
+ InterestOracleDatum,
27
+ InterestOracleParams,
28
+ mkCDPCreatorValidatorFromSP,
29
+ mkInterestOracleValidator,
30
+ mkPollManagerValidatorFromSP,
31
+ mkPollShardValidatorFromSP,
32
+ PollManagerParamsSP,
33
+ PollShardParamsSP,
34
+ PriceOracleDatum,
35
+ PriceOracleParams,
36
+ runOneShotMintTx,
37
+ serialiseGovDatum,
38
+ serialiseIAssetDatum,
39
+ serialiseInterestOracleDatum,
40
+ serialisePriceOracleDatum,
41
+ serialiseStabilityPoolDatum,
42
+ StabilityPoolContent,
43
+ StabilityPoolParamsSP,
44
+ StakingParams,
45
+ SystemParams,
46
+ toSystemParamsAsset,
47
+ TreasuryContract,
48
+ TreasuryParams,
49
+ VersionRecordParams,
50
+ } from '../../src';
51
+ import { mkAuthTokenPolicy } from '../../src/scripts/auth-token-policy';
52
+ import { StakingContract } from '../../src/contracts/staking';
53
+ import { serialiseStakingDatum } from '../../src/types/indigo/staking';
54
+ import { mkIAssetTokenPolicy } from '../../src/scripts/iasset-policy';
55
+ import { mkPriceOracleValidator } from '../../src/scripts/price-oracle-validator';
56
+ import { mkVersionRecordTokenPolicy } from '../../src/scripts/version-record-policy';
57
+ import { mkVersionRegistryValidator } from '../../src/scripts/version-registry';
58
+ import { mkExecuteValidatorFromSP } from '../../src/scripts/execute-validator';
59
+ import { mkGovValidatorFromSP } from '../../src/scripts/gov-validator';
60
+ import { mkStabilityPoolValidatorFromSP } from '../../src/scripts/stability-pool-validator';
61
+
62
+ const indyTokenName = 'INDY';
63
+ const daoTokenName = 'DAO';
64
+ const govNftTokenName = 'GOV_NFT';
65
+ const pollManagerTokenName = 'POLL_MANAGER';
66
+ // const pollShardTokenName = 'POLL_SHARD';
67
+ const upgradeTokenName = 'UPGRADE';
68
+ const iassetTokenName = 'IASSET';
69
+ const stabilityPoolTokenName = 'STABILITY_POOL';
70
+ const versionRecordTokenName = 'VERSION_RECORD';
71
+ const cdpCreatorTokenName = 'CDP_CREATOR';
72
+ const cdpTokenName = 'CDP';
73
+ const stakingManagerTokenName = 'STAKING_MANAGER';
74
+ const stakingTokenName = 'STAKING_POSITION';
75
+ const snapshotEpochToScaleToSumTokenName = 'SNAPSHOT_EPOCH_TO_SCALE_TO_SUM';
76
+ const accountTokenName = 'SP_ACCOUNT';
77
+
78
+ const totalIndySupply = 35000000000000n;
79
+ // const totalIndyDistribution = 0n;
80
+ const treasuryIndyAmount = 0n;
81
+
82
+ const numCdpCreators = 2n;
83
+ const numCollectors = 2n;
84
+
85
+ type InitialAsset = {
86
+ name: string;
87
+ priceOracle: {
88
+ tokenName: string;
89
+ startPrice: bigint;
90
+ params: {
91
+ biasTime: bigint;
92
+ expirationTime: bigint;
93
+ };
94
+ };
95
+ initerestOracle: {
96
+ tokenName: string;
97
+ initialInterestRate: bigint;
98
+ params: {
99
+ biasTime: bigint;
100
+ };
101
+ };
102
+ redemptionRatioPercentage: bigint;
103
+ maintenanceRatioPercentage: bigint;
104
+ liquidationRatioPercentage: bigint;
105
+ debtMintingFeePercentage: bigint;
106
+ liquidationProcessingFeePercentage: bigint;
107
+ stabilityPoolWithdrawalFeePercentage: bigint;
108
+ redemptionReimbursementPercentage: bigint;
109
+ redemptionProcessingFeePercentage: bigint;
110
+ interestCollectorPortionPercentage: bigint;
111
+ firstAsset: boolean;
112
+ nextAsset?: string;
113
+ };
114
+
115
+ const initialAssets: InitialAsset[] = [
116
+ {
117
+ name: 'iUSD',
118
+ priceOracle: {
119
+ tokenName: 'iUSD_ORACLE',
120
+ startPrice: 1_000_000n,
121
+ params: {
122
+ biasTime: 120_000n,
123
+ expirationTime: 1_800_000n,
124
+ },
125
+ },
126
+ initerestOracle: {
127
+ tokenName: 'iUSD_ORACLE',
128
+ initialInterestRate: 1_000_000n,
129
+ params: {
130
+ biasTime: 120_000n,
131
+ },
132
+ },
133
+ redemptionRatioPercentage: 200_000_000n,
134
+ maintenanceRatioPercentage: 150_000_000n,
135
+ liquidationRatioPercentage: 120_000_000n,
136
+ debtMintingFeePercentage: 500_000n,
137
+ liquidationProcessingFeePercentage: 2_000_000n,
138
+ stabilityPoolWithdrawalFeePercentage: 500_000n,
139
+ redemptionReimbursementPercentage: 1_000_000n,
140
+ redemptionProcessingFeePercentage: 1_000_000n,
141
+ interestCollectorPortionPercentage: 40_000_000n,
142
+ firstAsset: true,
143
+ nextAsset: null,
144
+ },
145
+ ];
146
+
147
+ const alwaysFailValidatorHash =
148
+ 'ea84d625650d066e1645e3e81d9c70a73f9ed837bd96dc49850ae744';
149
+
150
+ async function mintOneTimeToken(
151
+ lucid: LucidEvolution,
152
+ tokenName: string,
153
+ amount: bigint,
154
+ ): Promise<PolicyId> {
155
+ const utxos = await lucid.wallet().getUtxos();
156
+ return await runOneShotMintTx(lucid, {
157
+ referenceOutRef: {
158
+ txHash: utxos[0].txHash,
159
+ outputIdx: BigInt(utxos[0].outputIndex),
160
+ },
161
+ mintAmounts: [{ tokenName: tokenName, amount: amount }],
162
+ });
163
+ }
164
+
165
+ async function initScriptRef(
166
+ lucid: LucidEvolution,
167
+ validator: SpendingValidator,
168
+ ): Promise<Input> {
169
+ const tx = lucid.newTx().pay.ToContract(
170
+ credentialToAddress(lucid.config().network, {
171
+ hash: alwaysFailValidatorHash,
172
+ type: 'Script',
173
+ }),
174
+ null,
175
+ undefined,
176
+ validator,
177
+ );
178
+
179
+ const txHash = await tx
180
+ .complete()
181
+ .then((tx) => tx.sign.withWallet().complete())
182
+ .then((tx) => tx.submit());
183
+
184
+ await lucid.awaitTx(txHash);
185
+
186
+ return {
187
+ transactionId: txHash,
188
+ index: 0,
189
+ };
190
+ }
191
+
192
+ async function initCollector(
193
+ lucid: LucidEvolution,
194
+ collectorParams: CollectorParams,
195
+ ): Promise<void> {
196
+ const tx = lucid.newTx();
197
+
198
+ for (let i = 0; i < Number(numCollectors); i++) {
199
+ tx.pay.ToContract(CollectorContract.address(collectorParams, lucid), {
200
+ kind: 'inline',
201
+ value: Data.to(new Constr(0, [])),
202
+ });
203
+ }
204
+
205
+ const txHash = await tx
206
+ .complete()
207
+ .then((tx) => tx.sign.withWallet().complete())
208
+ .then((tx) => tx.submit());
209
+
210
+ await lucid.awaitTx(txHash);
211
+ }
212
+
213
+ async function initCDPCreator(
214
+ lucid: LucidEvolution,
215
+ cdpCreatorParams: CDPCreatorParamsSP,
216
+ ): Promise<void> {
217
+ const tx = lucid.newTx();
218
+
219
+ for (let i = 0; i < Number(numCdpCreators); i++) {
220
+ tx.pay.ToContract(
221
+ credentialToAddress(lucid.config().network, {
222
+ hash: validatorToScriptHash(
223
+ mkCDPCreatorValidatorFromSP(cdpCreatorParams),
224
+ ),
225
+ type: 'Script',
226
+ }),
227
+ { kind: 'inline', value: Data.to(new Constr(0, [])) },
228
+ {
229
+ [cdpCreatorParams.cdpCreatorNft[0].unCurrencySymbol +
230
+ fromText(cdpCreatorParams.cdpCreatorNft[1].unTokenName)]: 1n,
231
+ },
232
+ );
233
+ }
234
+
235
+ const txHash = await tx
236
+ .complete()
237
+ .then((tx) => tx.sign.withWallet().complete())
238
+ .then((tx) => tx.submit());
239
+
240
+ await lucid.awaitTx(txHash);
241
+ }
242
+
243
+ async function initTreasury(
244
+ lucid: LucidEvolution,
245
+ treasuryParams: TreasuryParams,
246
+ daoAsset: AssetClass,
247
+ indyAsset: AssetClass,
248
+ treasuryIndyAmount: bigint,
249
+ ): Promise<void> {
250
+ const tx = lucid.newTx().pay.ToContract(
251
+ credentialToAddress(lucid.config().network, {
252
+ hash: TreasuryContract.validatorHash(treasuryParams),
253
+ type: 'Script',
254
+ }),
255
+ { kind: 'inline', value: Data.to(new Constr(0, [])) },
256
+ {
257
+ [daoAsset.currencySymbol + daoAsset.tokenName]: 1n,
258
+ [indyAsset.currencySymbol + indyAsset.tokenName]: treasuryIndyAmount,
259
+ },
260
+ );
261
+
262
+ const txHash = await tx
263
+ .complete()
264
+ .then((tx) => tx.sign.withWallet().complete())
265
+ .then((tx) => tx.submit());
266
+
267
+ await lucid.awaitTx(txHash);
268
+ }
269
+
270
+ async function initStakingManager(
271
+ lucid: LucidEvolution,
272
+ stakingParams: StakingParams,
273
+ ): Promise<void> {
274
+ const txHash = await lucid
275
+ .newTx()
276
+ .pay.ToContract(
277
+ StakingContract.address(stakingParams, lucid),
278
+ {
279
+ kind: 'inline',
280
+ value: serialiseStakingDatum({
281
+ StakingManager: {
282
+ content: { totalStake: 0n, managerSnapshot: { snapshotAda: 0n } },
283
+ },
284
+ }),
285
+ },
286
+ {
287
+ lovelace: 5_000_000n,
288
+ [stakingParams.stakingManagerNFT[0].unCurrencySymbol +
289
+ fromText(stakingParams.stakingManagerNFT[1].unTokenName)]: 1n,
290
+ },
291
+ )
292
+ .complete()
293
+ .then((tx) => tx.sign.withWallet().complete())
294
+ .then((tx) => tx.submit());
295
+
296
+ await lucid.awaitTx(txHash);
297
+ }
298
+
299
+ async function startPriceOracleTx(
300
+ lucid: LucidEvolution,
301
+ assetName: string,
302
+ startPrice: bigint,
303
+ oracleParams: PriceOracleParams,
304
+ now: number = Date.now(),
305
+ ): Promise<string> {
306
+ const oraclePolicyId = await mintOneTimeToken(lucid, fromText(assetName), 1n);
307
+ const oracleValidator = mkPriceOracleValidator(oracleParams);
308
+
309
+ const oracleDatum: PriceOracleDatum = {
310
+ price: {
311
+ getOnChainInt: startPrice,
312
+ },
313
+ expiration: BigInt(now) + oracleParams.expiration,
314
+ };
315
+
316
+ const tx = lucid.newTx().pay.ToContract(
317
+ validatorToAddress(lucid.config().network, oracleValidator),
318
+ { kind: 'inline', value: serialisePriceOracleDatum(oracleDatum) },
319
+ {
320
+ lovelace: 5_000_000n,
321
+ [oraclePolicyId + fromText(assetName)]: 1n,
322
+ },
323
+ );
324
+
325
+ const txHash = await tx
326
+ .complete()
327
+ .then((tx) => tx.sign.withWallet().complete())
328
+ .then((tx) => tx.submit());
329
+
330
+ await lucid.awaitTx(txHash);
331
+
332
+ return oraclePolicyId;
333
+ }
334
+
335
+ async function startInterestOracleTx(
336
+ lucid: LucidEvolution,
337
+ assetName: string,
338
+ initialInterestRate: bigint,
339
+ oracleParams: InterestOracleParams,
340
+ ): Promise<string> {
341
+ const oraclePolicyId = await mintOneTimeToken(lucid, fromText(assetName), 1n);
342
+ const oracleValidator = mkInterestOracleValidator(oracleParams);
343
+
344
+ const oracleDatum: InterestOracleDatum = {
345
+ unitaryInterest: 0n,
346
+ lastUpdated: 0n,
347
+ interestRate: {
348
+ getOnChainInt: initialInterestRate,
349
+ },
350
+ };
351
+
352
+ const tx = lucid.newTx().pay.ToContract(
353
+ validatorToAddress(lucid.config().network, oracleValidator),
354
+ { kind: 'inline', value: serialiseInterestOracleDatum(oracleDatum) },
355
+ {
356
+ lovelace: 5_000_000n,
357
+ [oraclePolicyId + fromText(assetName)]: 1n,
358
+ },
359
+ );
360
+
361
+ const txHash = await tx
362
+ .complete()
363
+ .then((tx) => tx.sign.withWallet().complete())
364
+ .then((tx) => tx.submit());
365
+
366
+ await lucid.awaitTx(txHash);
367
+
368
+ return oraclePolicyId;
369
+ }
370
+
371
+ async function initializeAsset(
372
+ lucid: LucidEvolution,
373
+ cdpParams: CdpParams,
374
+ iassetToken: AssetClass,
375
+ stabilityPoolParams: StabilityPoolParamsSP,
376
+ stabilityPoolToken: AssetClass,
377
+ asset: InitialAsset,
378
+ now: number = Date.now(),
379
+ ): Promise<void> {
380
+ const [pkh, _] = await addrDetails(lucid);
381
+ const priceOracleTokenName = asset.name + '_ORACLE';
382
+ const priceOraclePolicyId = await startPriceOracleTx(
383
+ lucid,
384
+ priceOracleTokenName,
385
+ asset.priceOracle.startPrice,
386
+ {
387
+ owner: pkh.hash,
388
+ biasTime: asset.priceOracle.params.biasTime,
389
+ expiration: asset.priceOracle.params.expirationTime,
390
+ },
391
+ now,
392
+ );
393
+
394
+ const interestOracleTokenName = asset.name + '_ORACLE';
395
+ const interestOraclePolicyId = await startInterestOracleTx(
396
+ lucid,
397
+ interestOracleTokenName,
398
+ asset.initerestOracle.initialInterestRate,
399
+ {
400
+ owner: pkh.hash,
401
+ biasTime: asset.priceOracle.params.biasTime,
402
+ },
403
+ );
404
+
405
+ const iassetDatum: IAssetContent = {
406
+ assetName: fromText(asset.name),
407
+ price: {
408
+ Oracle: {
409
+ oracleNft: {
410
+ asset: {
411
+ currencySymbol: priceOraclePolicyId,
412
+ tokenName: fromText(priceOracleTokenName),
413
+ },
414
+ },
415
+ },
416
+ },
417
+ interestOracleNft: {
418
+ currencySymbol: interestOraclePolicyId,
419
+ tokenName: fromText(interestOracleTokenName),
420
+ },
421
+ redemptionRatio: { getOnChainInt: asset.redemptionRatioPercentage },
422
+ maintenanceRatio: { getOnChainInt: asset.maintenanceRatioPercentage },
423
+ liquidationRatio: { getOnChainInt: asset.liquidationRatioPercentage },
424
+ debtMintingFeePercentage: { getOnChainInt: asset.debtMintingFeePercentage },
425
+ liquidationProcessingFeePercentage: {
426
+ getOnChainInt: asset.liquidationProcessingFeePercentage,
427
+ },
428
+ stabilityPoolWithdrawalFeePercentage: {
429
+ getOnChainInt: asset.stabilityPoolWithdrawalFeePercentage,
430
+ },
431
+ redemptionReimbursementPercentage: {
432
+ getOnChainInt: asset.redemptionReimbursementPercentage,
433
+ },
434
+ redemptionProcessingFeePercentage: {
435
+ getOnChainInt: asset.redemptionProcessingFeePercentage,
436
+ },
437
+ interestCollectorPortionPercentage: {
438
+ getOnChainInt: asset.interestCollectorPortionPercentage,
439
+ },
440
+ firstIAsset: true,
441
+ nextIAsset: asset.nextAsset ? fromText(asset.nextAsset) : null,
442
+ };
443
+
444
+ const assetTx = lucid
445
+ .newTx()
446
+ .pay.ToContract(
447
+ CDPContract.address(cdpParams, lucid),
448
+ { kind: 'inline', value: serialiseIAssetDatum(iassetDatum) },
449
+ { [iassetToken.currencySymbol + iassetToken.tokenName]: 1n },
450
+ );
451
+
452
+ const assetTxHash = await assetTx
453
+ .complete()
454
+ .then((assetTx) => assetTx.sign.withWallet().complete())
455
+ .then((assetTx) => assetTx.submit());
456
+
457
+ await lucid.awaitTx(assetTxHash);
458
+
459
+ const stabilityPoolDatum: StabilityPoolContent = {
460
+ asset: fromText(asset.name),
461
+ snapshot: {
462
+ productVal: { value: 1n },
463
+ depositVal: { value: 0n },
464
+ sumVal: { value: 0n },
465
+ epoch: 0n,
466
+ scale: 0n,
467
+ },
468
+ epochToScaleToSum: new Map(),
469
+ };
470
+
471
+ const spTx = lucid.newTx().pay.ToContract(
472
+ credentialToAddress(lucid.config().network, {
473
+ hash: validatorToScriptHash(
474
+ mkStabilityPoolValidatorFromSP(stabilityPoolParams),
475
+ ),
476
+ type: 'Script',
477
+ }),
478
+ {
479
+ kind: 'inline',
480
+ value: serialiseStabilityPoolDatum({
481
+ StabilityPool: { content: stabilityPoolDatum },
482
+ }),
483
+ },
484
+ {
485
+ [stabilityPoolToken.currencySymbol + stabilityPoolToken.tokenName]: 1n,
486
+ },
487
+ );
488
+
489
+ const spTxHash = await spTx
490
+ .complete()
491
+ .then((spTx) => spTx.sign.withWallet().complete())
492
+ .then((spTx) => spTx.submit());
493
+
494
+ await lucid.awaitTx(spTxHash);
495
+ }
496
+
497
+ async function initGovernance(
498
+ lucid: LucidEvolution,
499
+ governanceParams: GovParamsSP,
500
+ govToken: AssetClass,
501
+ ): Promise<void> {
502
+ const datum: GovDatum = {
503
+ currentProposal: 0n,
504
+ currentVersion: 0n,
505
+ protocolParams: {
506
+ effectiveDelay: 1_000n,
507
+ expirationPeriod: 180_000n,
508
+ proposalDeposit: 0n,
509
+ proposingPeriod: 8_000n,
510
+ collateralFeePercentage: {
511
+ getOnChainInt: 1_500_000n,
512
+ },
513
+ votingPeriod: 10_000n,
514
+ totalShards: 4n,
515
+ minimumQuorum: 100_000n,
516
+ maxTreasuryLovelaceSpend: 10_000_000n,
517
+ maxTreasuryIndySpend: 10_000_000n,
518
+ },
519
+ activeProposals: 0n,
520
+ treasuryIndyWithdrawnAmt: 0n,
521
+ iassetsCount: BigInt(initialAssets.length),
522
+ };
523
+ const tx = lucid.newTx().pay.ToContract(
524
+ credentialToAddress(lucid.config().network, {
525
+ hash: validatorToScriptHash(mkGovValidatorFromSP(governanceParams)),
526
+ type: 'Script',
527
+ }),
528
+ { kind: 'inline', value: serialiseGovDatum(datum) },
529
+ {
530
+ [govToken.currencySymbol + govToken.tokenName]: 1n,
531
+ },
532
+ );
533
+
534
+ const txHash = await tx
535
+ .complete()
536
+ .then((tx) => tx.sign.withWallet().complete())
537
+ .then((tx) => tx.submit());
538
+
539
+ await lucid.awaitTx(txHash);
540
+ }
541
+
542
+ async function mintAuthTokenDirect(
543
+ lucid: LucidEvolution,
544
+ asset: AssetClass,
545
+ tokenName: string,
546
+ amount: bigint,
547
+ ): Promise<void> {
548
+ const script = mkAuthTokenPolicy(asset, fromText(tokenName));
549
+ const policyId = mintingPolicyToId(script);
550
+ const address = await lucid.wallet().address();
551
+ const utxos = await lucid.utxosAtWithUnit(
552
+ address,
553
+ asset.currencySymbol + asset.tokenName,
554
+ );
555
+ if (utxos.length === 0) {
556
+ throw new Error('No utxos found');
557
+ }
558
+
559
+ const tx = lucid
560
+ .newTx()
561
+ .attach.MintingPolicy(script)
562
+ .collectFrom(utxos)
563
+ .mintAssets(
564
+ {
565
+ [policyId + fromText(tokenName)]: amount,
566
+ },
567
+ Data.to(new Constr(0, [])),
568
+ );
569
+
570
+ const txHash = await tx
571
+ .complete()
572
+ .then((tx) => tx.sign.withWallet().complete())
573
+ .then((tx) => tx.submit());
574
+
575
+ await lucid.awaitTx(txHash);
576
+ }
577
+
578
+ export async function init(
579
+ lucid: LucidEvolution,
580
+ now: number = Date.now(),
581
+ ): Promise<SystemParams> {
582
+ const indyAsset: AssetClass = {
583
+ currencySymbol: await mintOneTimeToken(
584
+ lucid,
585
+ fromText(indyTokenName),
586
+ totalIndySupply,
587
+ ),
588
+ tokenName: fromText(indyTokenName),
589
+ };
590
+
591
+ const daoAsset: AssetClass = {
592
+ currencySymbol: await mintOneTimeToken(lucid, fromText(daoTokenName), 1n),
593
+ tokenName: fromText(daoTokenName),
594
+ };
595
+
596
+ const govNftAsset: AssetClass = {
597
+ currencySymbol: await mintOneTimeToken(
598
+ lucid,
599
+ fromText(govNftTokenName),
600
+ 1n,
601
+ ),
602
+ tokenName: fromText(govNftTokenName),
603
+ };
604
+
605
+ const pollTokenPolicy = mkAuthTokenPolicy(
606
+ govNftAsset,
607
+ fromText(pollManagerTokenName),
608
+ );
609
+ const pollToken: AssetClass = {
610
+ currencySymbol: mintingPolicyToId(pollTokenPolicy),
611
+ tokenName: fromText(pollManagerTokenName),
612
+ };
613
+
614
+ const upgradeTokenPolicy = mkAuthTokenPolicy(
615
+ pollToken,
616
+ fromText(upgradeTokenName),
617
+ );
618
+ const upgradeToken: AssetClass = {
619
+ currencySymbol: mintingPolicyToId(upgradeTokenPolicy),
620
+ tokenName: fromText(upgradeTokenName),
621
+ };
622
+
623
+ const iassetTokenPolicy = mkAuthTokenPolicy(
624
+ upgradeToken,
625
+ fromText(iassetTokenName),
626
+ );
627
+ const iassetToken: AssetClass = {
628
+ currencySymbol: mintingPolicyToId(iassetTokenPolicy),
629
+ tokenName: fromText(iassetTokenName),
630
+ };
631
+
632
+ const stabilityPoolTokenPolicy = mkAuthTokenPolicy(
633
+ upgradeToken,
634
+ fromText(stabilityPoolTokenName),
635
+ );
636
+ const stabilityPoolToken: AssetClass = {
637
+ currencySymbol: mintingPolicyToId(stabilityPoolTokenPolicy),
638
+ tokenName: fromText(stabilityPoolTokenName),
639
+ };
640
+ const versionRecordParams: VersionRecordParams = {
641
+ upgradeToken: toSystemParamsAsset(upgradeToken),
642
+ };
643
+ const versionRecordTokenPolicy = mkVersionRecordTokenPolicy({
644
+ upgradeToken,
645
+ });
646
+ const versionRecordToken: AssetClass = {
647
+ currencySymbol: mintingPolicyToId(versionRecordTokenPolicy),
648
+ tokenName: fromText(versionRecordTokenName),
649
+ };
650
+
651
+ const versionRegistryValidator = mkVersionRegistryValidator();
652
+ const versionRegistryValHash = validatorToScriptHash(
653
+ versionRegistryValidator,
654
+ );
655
+
656
+ const cdpCreatorAsset: AssetClass = {
657
+ currencySymbol: await mintOneTimeToken(
658
+ lucid,
659
+ fromText(cdpCreatorTokenName),
660
+ numCdpCreators,
661
+ ),
662
+ tokenName: fromText(cdpCreatorTokenName),
663
+ };
664
+
665
+ const cdpTokenPolicy = mkAuthTokenPolicy(
666
+ cdpCreatorAsset,
667
+ fromText(cdpTokenName),
668
+ );
669
+ const cdpToken: AssetClass = {
670
+ currencySymbol: mintingPolicyToId(cdpTokenPolicy),
671
+ tokenName: fromText(cdpTokenName),
672
+ };
673
+
674
+ const stakingManagerAsset: AssetClass = {
675
+ currencySymbol: await mintOneTimeToken(
676
+ lucid,
677
+ fromText(stakingManagerTokenName),
678
+ 1n,
679
+ ),
680
+ tokenName: fromText(stakingManagerTokenName),
681
+ };
682
+
683
+ const stakingTokenPolicy = mkAuthTokenPolicy(
684
+ stakingManagerAsset,
685
+ fromText(stakingTokenName),
686
+ );
687
+ const stakingToken: AssetClass = {
688
+ currencySymbol: mintingPolicyToId(stakingTokenPolicy),
689
+ tokenName: fromText(stakingTokenName),
690
+ };
691
+
692
+ const collectorParams: CollectorParams = {
693
+ stakingManagerNFT: toSystemParamsAsset(stakingManagerAsset),
694
+ stakingToken: toSystemParamsAsset(stakingToken),
695
+ versionRecordToken: toSystemParamsAsset(versionRecordToken),
696
+ };
697
+ const collectorValidator = CollectorContract.validator(collectorParams);
698
+ const collectorValHash = CollectorContract.validatorHash(collectorParams);
699
+
700
+ const stakingParams: StakingParams = {
701
+ stakingManagerNFT: toSystemParamsAsset(stakingManagerAsset),
702
+ stakingToken: toSystemParamsAsset(stakingToken),
703
+ versionRecordToken: toSystemParamsAsset(versionRecordToken),
704
+ pollToken: toSystemParamsAsset(pollToken),
705
+ indyToken: toSystemParamsAsset(indyAsset),
706
+ collectorValHash: collectorValHash,
707
+ };
708
+ const stakingValHash = StakingContract.validatorHash(stakingParams);
709
+
710
+ await initStakingManager(lucid, stakingParams);
711
+
712
+ const assetSymbolPolicy = mkIAssetTokenPolicy(cdpToken);
713
+ const assetSymbol = mintingPolicyToId(assetSymbolPolicy);
714
+
715
+ const snapshotEpochToScaleToSumTokenPolicy = mkAuthTokenPolicy(
716
+ stabilityPoolToken,
717
+ fromText(snapshotEpochToScaleToSumTokenName),
718
+ );
719
+ const snapshotEpochToScaleToSumToken: AssetClass = {
720
+ currencySymbol: mintingPolicyToId(snapshotEpochToScaleToSumTokenPolicy),
721
+ tokenName: fromText(snapshotEpochToScaleToSumTokenName),
722
+ };
723
+
724
+ const accountTokenPolicy = mkAuthTokenPolicy(
725
+ stabilityPoolToken,
726
+ fromText(accountTokenName),
727
+ );
728
+ const accountToken: AssetClass = {
729
+ currencySymbol: mintingPolicyToId(accountTokenPolicy),
730
+ tokenName: fromText(accountTokenName),
731
+ };
732
+
733
+ const stabilityPoolParams: StabilityPoolParamsSP = {
734
+ assetSymbol: { unCurrencySymbol: assetSymbol },
735
+ stabilityPoolToken: toSystemParamsAsset(stabilityPoolToken),
736
+ snapshotEpochToScaleToSumToken: toSystemParamsAsset(
737
+ snapshotEpochToScaleToSumToken,
738
+ ),
739
+ accountToken: toSystemParamsAsset(accountToken),
740
+ cdpToken: toSystemParamsAsset(cdpToken),
741
+ iAssetAuthToken: toSystemParamsAsset(iassetToken),
742
+ versionRecordToken: toSystemParamsAsset(versionRecordToken),
743
+ collectorValHash: collectorValHash,
744
+ govNFT: toSystemParamsAsset(govNftAsset),
745
+ accountCreateFeeLovelaces: 5_000_000,
746
+ accountAdjustmentFeeLovelaces: 5_000_000,
747
+ requestCollateralLovelaces: 5_000_000,
748
+ };
749
+ const stabilityPoolValidator =
750
+ mkStabilityPoolValidatorFromSP(stabilityPoolParams);
751
+ const stabilityPoolValHash = validatorToScriptHash(stabilityPoolValidator);
752
+
753
+ const treasuryParams: TreasuryParams = {
754
+ upgradeToken: toSystemParamsAsset(upgradeToken),
755
+ versionRecordToken: toSystemParamsAsset(versionRecordToken),
756
+ treasuryUtxosStakeCredential: null,
757
+ };
758
+
759
+ const treasuryValidator = TreasuryContract.validator(treasuryParams);
760
+ const treasuryValHash = TreasuryContract.validatorHash(treasuryParams);
761
+
762
+ await initTreasury(
763
+ lucid,
764
+ treasuryParams,
765
+ daoAsset,
766
+ indyAsset,
767
+ treasuryIndyAmount,
768
+ );
769
+
770
+ const cdpParams: CdpParams = {
771
+ cdpAuthToken: toSystemParamsAsset(cdpToken),
772
+ cdpAssetSymbol: { unCurrencySymbol: assetSymbol },
773
+ iAssetAuthToken: toSystemParamsAsset(iassetToken),
774
+ stabilityPoolAuthToken: toSystemParamsAsset(stabilityPoolToken),
775
+ versionRecordToken: toSystemParamsAsset(versionRecordToken),
776
+ upgradeToken: toSystemParamsAsset(upgradeToken),
777
+ collectorValHash: collectorValHash,
778
+ spValHash: stabilityPoolValHash,
779
+ govNFT: toSystemParamsAsset(govNftAsset),
780
+ minCollateralInLovelace: 10_000_000,
781
+ partialRedemptionExtraFeeLovelace: 10_000_000,
782
+ biasTime: 120_000,
783
+ treasuryValHash: treasuryValHash,
784
+ };
785
+ const cdpValHash = CDPContract.validatorHash(cdpParams);
786
+
787
+ const cdpCreatorParams: CDPCreatorParamsSP = {
788
+ cdpCreatorNft: toSystemParamsAsset(cdpCreatorAsset),
789
+ cdpAssetCs: { unCurrencySymbol: assetSymbol },
790
+ cdpAuthTk: toSystemParamsAsset(cdpToken),
791
+ iAssetAuthTk: toSystemParamsAsset(iassetToken),
792
+ versionRecordToken: toSystemParamsAsset(versionRecordToken),
793
+ cdpScriptHash: cdpValHash,
794
+ collectorValHash: collectorValHash,
795
+ minCollateralInLovelace: 10_000_000,
796
+ biasTime: 8_000n,
797
+ };
798
+ const cdpCreatorValidator = mkCDPCreatorValidatorFromSP(cdpCreatorParams);
799
+ const cdpCreatorValHash = validatorToScriptHash(cdpCreatorValidator);
800
+
801
+ await initCDPCreator(lucid, cdpCreatorParams);
802
+ await initCollector(lucid, collectorParams);
803
+
804
+ if (initialAssets.length > 0) {
805
+ await mintAuthTokenDirect(lucid, govNftAsset, pollManagerTokenName, 1n);
806
+ await mintAuthTokenDirect(lucid, pollToken, upgradeTokenName, 1n);
807
+
808
+ for (const asset of initialAssets) {
809
+ await mintAuthTokenDirect(lucid, upgradeToken, iassetTokenName, 1n);
810
+ await mintAuthTokenDirect(
811
+ lucid,
812
+ upgradeToken,
813
+ stabilityPoolTokenName,
814
+ 1n,
815
+ );
816
+
817
+ await initializeAsset(
818
+ lucid,
819
+ cdpParams,
820
+ iassetToken,
821
+ stabilityPoolParams,
822
+ stabilityPoolToken,
823
+ asset,
824
+ now,
825
+ );
826
+ }
827
+
828
+ await mintAuthTokenDirect(lucid, pollToken, upgradeTokenName, -1n);
829
+ await mintAuthTokenDirect(lucid, govNftAsset, pollManagerTokenName, -1n);
830
+ }
831
+
832
+ const executeParams: ExecuteParamsSP = {
833
+ govNFT: toSystemParamsAsset(govNftAsset),
834
+ upgradeToken: toSystemParamsAsset(upgradeToken),
835
+ iAssetToken: toSystemParamsAsset(iassetToken),
836
+ stabilityPoolToken: toSystemParamsAsset(stabilityPoolToken),
837
+ versionRecordToken: toSystemParamsAsset(versionRecordToken),
838
+ cdpValHash: cdpValHash,
839
+ sPoolValHash: stabilityPoolValHash,
840
+ versionRegistryValHash: versionRegistryValHash,
841
+ treasuryValHash: treasuryValHash,
842
+ indyAsset: toSystemParamsAsset(indyAsset),
843
+ };
844
+ const executeValidator = mkExecuteValidatorFromSP(executeParams);
845
+ const executeValHash = validatorToScriptHash(executeValidator);
846
+
847
+ const pollShardParams: PollShardParamsSP = {
848
+ pollToken: toSystemParamsAsset(pollToken),
849
+ stakingToken: toSystemParamsAsset(stakingToken),
850
+ indyAsset: toSystemParamsAsset(indyAsset),
851
+ stakingValHash: stakingValHash,
852
+ };
853
+ const pollShardValidator = mkPollShardValidatorFromSP(pollShardParams);
854
+ const pollShardValHash = validatorToScriptHash(pollShardValidator);
855
+
856
+ const pollManagerParams: PollManagerParamsSP = {
857
+ govNFT: toSystemParamsAsset(govNftAsset),
858
+ pollToken: toSystemParamsAsset(pollToken),
859
+ upgradeToken: toSystemParamsAsset(upgradeToken),
860
+ indyAsset: toSystemParamsAsset(indyAsset),
861
+ govExecuteValHash: executeValHash,
862
+ pBiasTime: 120_000n,
863
+ shardsValHash: pollShardValHash,
864
+ treasuryValHash: treasuryValHash,
865
+ initialIndyDistribution: 1_575_000_000_000n,
866
+ };
867
+ const pollManagerValidator = mkPollManagerValidatorFromSP(pollManagerParams);
868
+ const pollManagerValHash = validatorToScriptHash(pollManagerValidator);
869
+
870
+ const govParams: GovParamsSP = {
871
+ gBiasTime: 120_000n,
872
+ govNFT: toSystemParamsAsset(govNftAsset),
873
+ pollToken: toSystemParamsAsset(pollToken),
874
+ upgradeToken: toSystemParamsAsset(upgradeToken),
875
+ indyAsset: toSystemParamsAsset(indyAsset),
876
+ versionRecordToken: toSystemParamsAsset(versionRecordToken),
877
+ pollManagerValHash: pollManagerValHash,
878
+ daoIdentityToken: toSystemParamsAsset(daoAsset),
879
+ iAssetAuthToken: toSystemParamsAsset(iassetToken),
880
+ };
881
+ const govValidator = mkGovValidatorFromSP(govParams);
882
+ const govValHash = validatorToScriptHash(govValidator);
883
+
884
+ await initGovernance(lucid, govParams, govNftAsset);
885
+
886
+ return {
887
+ cdpParams: cdpParams,
888
+ cdpCreatorParams: cdpCreatorParams,
889
+ collectorParams: collectorParams,
890
+ executeParams: executeParams,
891
+ govParams: govParams,
892
+ stakingParams: stakingParams,
893
+ stabilityPoolParams: stabilityPoolParams,
894
+ treasuryParams: treasuryParams,
895
+ pollShardParams: pollShardParams,
896
+ pollManagerParams: pollManagerParams,
897
+ indyToken: toSystemParamsAsset(indyAsset),
898
+ distributionParams: {
899
+ treasuryIndyAmount: 1_575_000_000_000,
900
+ totalINDYSupply: 35_000_000_000_000,
901
+ initialIndyDistribution: 1_575_000_000_000,
902
+ },
903
+ versionRecordParams: versionRecordParams,
904
+ startTime: {
905
+ slot: 0,
906
+ blockHeader: '',
907
+ },
908
+ scriptReferences: {
909
+ cdpCreatorValidatorRef: {
910
+ input: await initScriptRef(lucid, cdpCreatorValidator),
911
+ },
912
+ cdpValidatorRef: {
913
+ input: await initScriptRef(lucid, CDPContract.validator(cdpParams)),
914
+ },
915
+ collectorValidatorRef: {
916
+ input: await initScriptRef(lucid, collectorValidator),
917
+ },
918
+ executeValidatorRef: {
919
+ input: await initScriptRef(lucid, executeValidator),
920
+ },
921
+ govValidatorRef: {
922
+ input: await initScriptRef(lucid, govValidator),
923
+ },
924
+ pollShardValidatorRef: {
925
+ input: await initScriptRef(lucid, pollShardValidator),
926
+ },
927
+ pollManagerValidatorRef: {
928
+ input: await initScriptRef(lucid, pollManagerValidator),
929
+ },
930
+ iAssetTokenPolicyRef: {
931
+ input: await initScriptRef(lucid, assetSymbolPolicy),
932
+ },
933
+ stakingValidatorRef: {
934
+ input: await initScriptRef(
935
+ lucid,
936
+ StakingContract.validator(stakingParams),
937
+ ),
938
+ },
939
+ stabilityPoolValidatorRef: {
940
+ input: await initScriptRef(lucid, stabilityPoolValidator),
941
+ },
942
+ treasuryValidatorRef: {
943
+ input: await initScriptRef(lucid, treasuryValidator),
944
+ },
945
+ governanceValidatorRef: {
946
+ input: await initScriptRef(lucid, govValidator),
947
+ },
948
+ versionRegistryValidatorRef: {
949
+ input: await initScriptRef(lucid, versionRegistryValidator),
950
+ },
951
+ versionRecordTokenPolicyRef: {
952
+ input: await initScriptRef(lucid, versionRecordTokenPolicy),
953
+ },
954
+ liquidityValidatorRef: {
955
+ input: undefined,
956
+ },
957
+ vestingValidatorRef: {
958
+ input: undefined,
959
+ },
960
+ authTokenPolicies: {
961
+ cdpAuthTokenRef: {
962
+ input: await initScriptRef(lucid, cdpTokenPolicy),
963
+ },
964
+ iAssetAuthTokenRef: {
965
+ input: await initScriptRef(lucid, iassetTokenPolicy),
966
+ },
967
+ accountTokenRef: {
968
+ input: await initScriptRef(lucid, accountTokenPolicy),
969
+ },
970
+ stabilityPoolAuthTokenRef: {
971
+ input: await initScriptRef(lucid, stabilityPoolTokenPolicy),
972
+ },
973
+ pollManagerTokenRef: {
974
+ input: await initScriptRef(lucid, pollTokenPolicy),
975
+ },
976
+ stakingTokenRef: {
977
+ input: await initScriptRef(lucid, stakingTokenPolicy),
978
+ },
979
+ versionRecordTokenRef: {
980
+ input: await initScriptRef(lucid, versionRecordTokenPolicy),
981
+ },
982
+ iAssetTokenRef: {
983
+ input: await initScriptRef(lucid, assetSymbolPolicy),
984
+ },
985
+ upgradeTokenRef: {
986
+ input: await initScriptRef(lucid, upgradeTokenPolicy),
987
+ },
988
+ stabilityPoolTokenRef: {
989
+ input: await initScriptRef(lucid, stabilityPoolTokenPolicy),
990
+ },
991
+ snapshotEpochToScaleToSumTokenRef: {
992
+ input: await initScriptRef(
993
+ lucid,
994
+ snapshotEpochToScaleToSumTokenPolicy,
995
+ ),
996
+ },
997
+ },
998
+ },
999
+ validatorHashes: {
1000
+ cdpCreatorHash: cdpCreatorValHash,
1001
+ cdpHash: cdpValHash,
1002
+ executeHash: executeValHash,
1003
+ govHash: govValHash,
1004
+ pollShardHash: pollShardValHash,
1005
+ pollManagerHash: pollManagerValHash,
1006
+ treasuryHash: treasuryValHash,
1007
+ stabilityPoolHash: stabilityPoolValHash,
1008
+ stakingHash: stakingValHash,
1009
+ collectorHash: collectorValHash,
1010
+ versionRegistryHash: versionRegistryValHash,
1011
+ },
1012
+ } as SystemParams;
1013
+ }