@indigo-labs/indigo-sdk 0.1.3 → 0.1.5

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 (85) hide show
  1. package/package.json +5 -2
  2. package/.github/workflows/ci.yml +0 -62
  3. package/.github/workflows/test.yml +0 -44
  4. package/.husky/pre-commit +0 -1
  5. package/.nvmrc +0 -1
  6. package/.prettierrc +0 -6
  7. package/eslint.config.mjs +0 -35
  8. package/src/contracts/cdp.ts +0 -741
  9. package/src/contracts/collector.ts +0 -98
  10. package/src/contracts/gov.ts +0 -1
  11. package/src/contracts/interest-oracle.ts +0 -149
  12. package/src/contracts/lrp.ts +0 -223
  13. package/src/contracts/one-shot.ts +0 -67
  14. package/src/contracts/stability-pool.ts +0 -684
  15. package/src/contracts/staking.ts +0 -348
  16. package/src/contracts/treasury.ts +0 -112
  17. package/src/helpers/asset-helpers.ts +0 -57
  18. package/src/helpers/helper-txs.ts +0 -30
  19. package/src/helpers/helpers.ts +0 -38
  20. package/src/helpers/indigo-helpers.ts +0 -19
  21. package/src/helpers/interest-oracle.ts +0 -57
  22. package/src/helpers/lucid-utils.ts +0 -70
  23. package/src/helpers/price-oracle-helpers.ts +0 -36
  24. package/src/helpers/stability-pool-helpers.ts +0 -207
  25. package/src/helpers/staking-helpers.ts +0 -94
  26. package/src/helpers/time-helpers.ts +0 -4
  27. package/src/helpers/value-helpers.ts +0 -16
  28. package/src/index.ts +0 -34
  29. package/src/scripts/always-fail-validator.ts +0 -7
  30. package/src/scripts/auth-token-policy.ts +0 -23
  31. package/src/scripts/cdp-creator-validator.ts +0 -53
  32. package/src/scripts/cdp-validator.ts +0 -9
  33. package/src/scripts/collector-validator.ts +0 -8
  34. package/src/scripts/execute-validator.ts +0 -52
  35. package/src/scripts/gov-validator.ts +0 -44
  36. package/src/scripts/iasset-policy.ts +0 -22
  37. package/src/scripts/interest-oracle-validator.ts +0 -23
  38. package/src/scripts/lrp-validator.ts +0 -23
  39. package/src/scripts/one-shot-policy.ts +0 -62
  40. package/src/scripts/poll-manager-validator.ts +0 -52
  41. package/src/scripts/poll-shard-validator.ts +0 -47
  42. package/src/scripts/price-oracle-validator.ts +0 -26
  43. package/src/scripts/stability-pool-validator.ts +0 -60
  44. package/src/scripts/staking-validator.ts +0 -8
  45. package/src/scripts/treasury-validator.ts +0 -8
  46. package/src/scripts/version-record-policy.ts +0 -26
  47. package/src/scripts/version-registry.ts +0 -15
  48. package/src/types/generic.ts +0 -106
  49. package/src/types/indigo/cdp-creator.ts +0 -46
  50. package/src/types/indigo/cdp.ts +0 -88
  51. package/src/types/indigo/execute.ts +0 -21
  52. package/src/types/indigo/gov.ts +0 -51
  53. package/src/types/indigo/interest-oracle.ts +0 -55
  54. package/src/types/indigo/lrp.ts +0 -54
  55. package/src/types/indigo/poll-manager.ts +0 -21
  56. package/src/types/indigo/poll-shard.ts +0 -16
  57. package/src/types/indigo/price-oracle.ts +0 -38
  58. package/src/types/indigo/stability-pool.ts +0 -233
  59. package/src/types/indigo/staking.ts +0 -99
  60. package/src/types/indigo/version-record.ts +0 -17
  61. package/src/types/on-chain-decimal.ts +0 -23
  62. package/src/types/one-shot.ts +0 -22
  63. package/src/types/system-params.ts +0 -246
  64. package/tests/data/system-params.json +0 -989
  65. package/tests/datums.test.ts +0 -286
  66. package/tests/endpoints/initialize.ts +0 -1013
  67. package/tests/hash-checks.test.ts +0 -73
  68. package/tests/indigo-test-helpers.ts +0 -115
  69. package/tests/initialize.test.ts +0 -27
  70. package/tests/interest-calculations.test.ts +0 -120
  71. package/tests/interest-oracle.test.ts +0 -90
  72. package/tests/lrp.test.ts +0 -149
  73. package/tests/queries/governance-queries.ts +0 -31
  74. package/tests/queries/iasset-queries.ts +0 -39
  75. package/tests/queries/interest-oracle-queries.ts +0 -13
  76. package/tests/queries/lrp-queries.ts +0 -39
  77. package/tests/queries/price-oracle-queries.ts +0 -27
  78. package/tests/queries/stability-pool-queries.ts +0 -75
  79. package/tests/queries/staking-queries.ts +0 -43
  80. package/tests/stability-pool.test.ts +0 -364
  81. package/tests/staking.test.ts +0 -105
  82. package/tests/test-helpers.ts +0 -38
  83. package/tsconfig.build.json +0 -4
  84. package/tsconfig.json +0 -16
  85. package/vitest.config.ts +0 -9
@@ -1,741 +0,0 @@
1
- import {
2
- applyParamsToScript,
3
- Assets,
4
- Constr,
5
- Credential,
6
- credentialToAddress,
7
- Data,
8
- fromText,
9
- LucidEvolution,
10
- OutRef,
11
- SpendingValidator,
12
- TxBuilder,
13
- UTxO,
14
- validatorToAddress,
15
- validatorToScriptHash,
16
- } from '@lucid-evolution/lucid';
17
- import {
18
- CdpParams,
19
- ScriptReferences,
20
- SystemParams,
21
- } from '../types/system-params';
22
- import { IAssetHelpers, IAssetOutput } from '../helpers/asset-helpers';
23
- import { CollectorContract } from './collector';
24
- import { TreasuryContract } from './treasury';
25
- import { addrDetails, scriptRef } from '../helpers/lucid-utils';
26
- import {
27
- calculateFeeFromPercentage,
28
- getRandomElement,
29
- } from '../helpers/helpers';
30
- import {
31
- CDPContent,
32
- parseCDPDatum,
33
- serialiseCDPDatum,
34
- } from '../types/indigo/cdp';
35
- import { _cdpValidator } from '../scripts/cdp-validator';
36
- import { parsePriceOracleDatum } from '../types/indigo/price-oracle';
37
- import { parseInterestOracleDatum } from '../types/indigo/interest-oracle';
38
- import { castCDPCreatorRedeemer } from '../types/indigo/cdp-creator';
39
- import { parseGovDatum } from '../types/indigo/gov';
40
- import {
41
- calculateAccruedInterest,
42
- calculateUnitaryInterestSinceOracleLastUpdated,
43
- } from '../helpers/interest-oracle';
44
-
45
- export class CDPContract {
46
- static async openPosition(
47
- asset: string,
48
- collateralAmount: bigint,
49
- mintedAmount: bigint,
50
- params: SystemParams,
51
- lucid: LucidEvolution,
52
- assetRef?: OutRef,
53
- priceOracleRef?: OutRef,
54
- interestOracleRef?: OutRef,
55
- cdpCreatorRef?: OutRef,
56
- collectorRef?: OutRef,
57
- now: number = Date.now(),
58
- ): Promise<TxBuilder> {
59
- const [pkh, skh] = await addrDetails(lucid);
60
- const assetOut: IAssetOutput = await (assetRef
61
- ? IAssetHelpers.findIAssetByRef(assetRef, lucid)
62
- : IAssetHelpers.findIAssetByName(asset, params, lucid));
63
- if (!assetOut || !assetOut.datum) throw new Error('Unable to find IAsset');
64
- // Fail if delisted asset
65
- if ('Delisted' in assetOut.datum.price)
66
- return Promise.reject(
67
- new Error('Trying to open CDP against delisted asset'),
68
- );
69
-
70
- const oracleAsset = assetOut.datum.price.Oracle.oracleNft.asset;
71
- const oracleOut = priceOracleRef
72
- ? (await lucid.utxosByOutRef([priceOracleRef]))[0]
73
- : await lucid.utxoByUnit(
74
- oracleAsset.currencySymbol + oracleAsset.tokenName,
75
- );
76
- if (!oracleOut.datum)
77
- return Promise.reject(new Error('Price Oracle datum not found'));
78
- const oracleDatum = parsePriceOracleDatum(oracleOut.datum);
79
-
80
- const interestOracleAsset = assetOut.datum.interestOracleNft;
81
- const interestOracleOut = interestOracleRef
82
- ? (await lucid.utxosByOutRef([interestOracleRef]))[0]
83
- : await lucid.utxoByUnit(
84
- interestOracleAsset.currencySymbol + interestOracleAsset.tokenName,
85
- );
86
- if (!interestOracleOut.datum)
87
- return Promise.reject(new Error('Interest Oracle datum not found'));
88
- const interestOracleDatum = parseInterestOracleDatum(
89
- interestOracleOut.datum,
90
- );
91
-
92
- const cdpCreatorOut = getRandomElement(
93
- cdpCreatorRef
94
- ? await lucid.utxosByOutRef([cdpCreatorRef])
95
- : await lucid.utxosAtWithUnit(
96
- credentialToAddress(lucid.config().network, {
97
- type: 'Script',
98
- hash: params.validatorHashes.cdpCreatorHash,
99
- }),
100
- params.cdpCreatorParams.cdpCreatorNft[0].unCurrencySymbol +
101
- fromText(params.cdpCreatorParams.cdpCreatorNft[1].unTokenName),
102
- ),
103
- );
104
-
105
- const cdpCreatorRedeemer = castCDPCreatorRedeemer({
106
- CreateCDP: {
107
- cdpOwner: pkh.hash,
108
- minted: mintedAmount,
109
- collateral: collateralAmount,
110
- currentTime: BigInt(now),
111
- },
112
- });
113
-
114
- const cdpCreatorScriptRefUtxo = await scriptRef(
115
- params.scriptReferences.cdpCreatorValidatorRef,
116
- lucid,
117
- );
118
-
119
- const cdpAddress = CDPContract.address(params.cdpParams, lucid, skh);
120
- const cdpToken =
121
- params.cdpParams.cdpAuthToken[0].unCurrencySymbol +
122
- fromText(params.cdpParams.cdpAuthToken[1].unTokenName);
123
-
124
- const cdpValue: Assets = {
125
- lovelace: collateralAmount,
126
- };
127
- cdpValue[cdpToken] = 1n;
128
- const newSnapshot =
129
- calculateUnitaryInterestSinceOracleLastUpdated(
130
- BigInt(now),
131
- interestOracleDatum,
132
- ) + interestOracleDatum.unitaryInterest;
133
- const cdpDatum: CDPContent = {
134
- cdpOwner: pkh.hash,
135
- iasset: fromText(asset),
136
- mintedAmt: mintedAmount,
137
- cdpFees: {
138
- ActiveCDPInterestTracking: {
139
- lastSettled: BigInt(now),
140
- unitaryInterestSnapshot: newSnapshot,
141
- },
142
- },
143
- };
144
-
145
- const assetToken =
146
- params.cdpParams.cdpAssetSymbol.unCurrencySymbol + fromText(asset);
147
- const cdpTokenMintValue: Assets = {};
148
- cdpTokenMintValue[cdpToken] = 1n;
149
- const iassetTokenMintValue: Assets = {};
150
- iassetTokenMintValue[assetToken] = BigInt(mintedAmount);
151
-
152
- const cdpAuthTokenScriptRefUtxo = await CDPContract.cdpAuthTokenRef(
153
- params.scriptReferences,
154
- lucid,
155
- );
156
- const iAssetTokenScriptRefUtxo = await CDPContract.assetTokenRef(
157
- params.scriptReferences,
158
- lucid,
159
- );
160
-
161
- const debtMintingFee = calculateFeeFromPercentage(
162
- BigInt(assetOut.datum.debtMintingFeePercentage.getOnChainInt),
163
- (mintedAmount * oracleDatum.price.getOnChainInt) / 1_000_000n,
164
- );
165
-
166
- // Oracle timestamp - 20s (length of a slot)
167
- const cappedValidateTo = oracleDatum.expiration - 20_001n;
168
- const timeValidFrom = now - 1_000;
169
- const timeValidTo_ = now + Number(params.cdpCreatorParams.biasTime) - 1_000;
170
- const timeValidTo =
171
- cappedValidateTo <= timeValidFrom
172
- ? timeValidTo_
173
- : Math.min(timeValidTo_, Number(cappedValidateTo));
174
-
175
- const tx = lucid
176
- .newTx()
177
- .collectFrom([cdpCreatorOut], Data.to(cdpCreatorRedeemer))
178
- .readFrom([cdpCreatorScriptRefUtxo])
179
- .pay.ToContract(
180
- cdpAddress,
181
- { kind: 'inline', value: serialiseCDPDatum(cdpDatum) },
182
- cdpValue,
183
- )
184
- .pay.ToContract(
185
- cdpCreatorOut.address,
186
- { kind: 'inline', value: cdpCreatorOut.datum },
187
- cdpCreatorOut.assets,
188
- )
189
- .readFrom([oracleOut, interestOracleOut, assetOut.utxo])
190
- .mintAssets(cdpTokenMintValue, Data.to(new Constr(0, [])))
191
- .readFrom([cdpAuthTokenScriptRefUtxo])
192
- .mintAssets(iassetTokenMintValue, Data.to(new Constr(0, [])))
193
- .readFrom([iAssetTokenScriptRefUtxo])
194
- .addSignerKey(pkh.hash)
195
- .validFrom(Number(now - 100))
196
- .validTo(Number(timeValidTo));
197
-
198
- if (debtMintingFee > 0) {
199
- await CollectorContract.feeTx(
200
- debtMintingFee,
201
- lucid,
202
- params,
203
- tx,
204
- collectorRef,
205
- );
206
- }
207
- return tx;
208
- }
209
-
210
- static async deposit(
211
- cdpRef: OutRef,
212
- amount: bigint,
213
- params: SystemParams,
214
- lucid: LucidEvolution,
215
- assetRef?: OutRef,
216
- priceOracleRef?: OutRef,
217
- interestOracleRef?: OutRef,
218
- collectorRef?: OutRef,
219
- govRef?: OutRef,
220
- treasuryRef?: OutRef,
221
- ): Promise<TxBuilder> {
222
- return CDPContract.adjust(
223
- cdpRef,
224
- amount,
225
- 0n,
226
- params,
227
- lucid,
228
- assetRef,
229
- priceOracleRef,
230
- interestOracleRef,
231
- collectorRef,
232
- govRef,
233
- treasuryRef,
234
- );
235
- }
236
-
237
- static async withdraw(
238
- cdpRef: OutRef,
239
- amount: bigint,
240
- params: SystemParams,
241
- lucid: LucidEvolution,
242
- assetRef?: OutRef,
243
- priceOracleRef?: OutRef,
244
- interestOracleRef?: OutRef,
245
- collectorRef?: OutRef,
246
- govRef?: OutRef,
247
- treasuryRef?: OutRef,
248
- ): Promise<TxBuilder> {
249
- return CDPContract.adjust(
250
- cdpRef,
251
- -amount,
252
- 0n,
253
- params,
254
- lucid,
255
- assetRef,
256
- priceOracleRef,
257
- interestOracleRef,
258
- collectorRef,
259
- govRef,
260
- treasuryRef,
261
- );
262
- }
263
-
264
- static async mint(
265
- cdpRef: OutRef,
266
- amount: bigint,
267
- params: SystemParams,
268
- lucid: LucidEvolution,
269
- assetRef?: OutRef,
270
- priceOracleRef?: OutRef,
271
- interestOracleRef?: OutRef,
272
- collectorRef?: OutRef,
273
- govRef?: OutRef,
274
- treasuryRef?: OutRef,
275
- ): Promise<TxBuilder> {
276
- return CDPContract.adjust(
277
- cdpRef,
278
- 0n,
279
- amount,
280
- params,
281
- lucid,
282
- assetRef,
283
- priceOracleRef,
284
- interestOracleRef,
285
- collectorRef,
286
- govRef,
287
- treasuryRef,
288
- );
289
- }
290
-
291
- static async burn(
292
- cdpRef: OutRef,
293
- amount: bigint,
294
- params: SystemParams,
295
- lucid: LucidEvolution,
296
- assetRef?: OutRef,
297
- priceOracleRef?: OutRef,
298
- interestOracleRef?: OutRef,
299
- collectorRef?: OutRef,
300
- govRef?: OutRef,
301
- treasuryRef?: OutRef,
302
- ): Promise<TxBuilder> {
303
- return CDPContract.adjust(
304
- cdpRef,
305
- 0n,
306
- -amount,
307
- params,
308
- lucid,
309
- assetRef,
310
- priceOracleRef,
311
- interestOracleRef,
312
- collectorRef,
313
- govRef,
314
- treasuryRef,
315
- );
316
- }
317
-
318
- static async adjust(
319
- cdpRef: OutRef,
320
- collateralAmount: bigint,
321
- mintAmount: bigint,
322
- params: SystemParams,
323
- lucid: LucidEvolution,
324
- assetRef?: OutRef,
325
- priceOracleRef?: OutRef,
326
- interestOracleRef?: OutRef,
327
- collectorRef?: OutRef,
328
- govRef?: OutRef,
329
- treasuryRef?: OutRef,
330
- ): Promise<TxBuilder> {
331
- // Find Pkh, Skh
332
- const [pkh, _] = await addrDetails(lucid);
333
- const now = Date.now();
334
-
335
- // Find Outputs: iAsset Output, CDP Output, Gov Output
336
- const cdp = (await lucid.utxosByOutRef([cdpRef]))[0];
337
- if (!cdp.datum) throw new Error('Unable to find CDP Datum');
338
- const cdpDatum = parseCDPDatum(cdp.datum);
339
- const iAsset = await (assetRef
340
- ? IAssetHelpers.findIAssetByRef(assetRef, lucid)
341
- : IAssetHelpers.findIAssetByName(cdpDatum.iasset, params, lucid));
342
-
343
- const gov = govRef
344
- ? (await lucid.utxosByOutRef([govRef]))[0]
345
- : await lucid.utxoByUnit(
346
- params.govParams.govNFT[0].unCurrencySymbol +
347
- fromText(params.govParams.govNFT[1].unTokenName),
348
- );
349
- if (!gov.datum) throw new Error('Unable to find Gov Datum');
350
- const govData = parseGovDatum(gov.datum);
351
- const cdpScriptRefUtxo = await CDPContract.scriptRef(
352
- params.scriptReferences,
353
- lucid,
354
- );
355
- const cdpAssets = Object.assign({}, cdp.assets);
356
- cdpAssets['lovelace'] = cdp.assets['lovelace'] + collateralAmount;
357
-
358
- const interestOracleAsset = iAsset.datum.interestOracleNft;
359
- const interestOracleOut = interestOracleRef
360
- ? (await lucid.utxosByOutRef([interestOracleRef]))[0]
361
- : await lucid.utxoByUnit(
362
- interestOracleAsset.currencySymbol +
363
- fromText(interestOracleAsset.tokenName),
364
- );
365
- if (!interestOracleOut.datum)
366
- return Promise.reject(new Error('Interest Oracle datum not found'));
367
- const interestOracleDatum = parseInterestOracleDatum(
368
- interestOracleOut.datum,
369
- );
370
-
371
- const tx = lucid
372
- .newTx()
373
- .collectFrom(
374
- [cdp],
375
- Data.to(new Constr(0, [BigInt(now), mintAmount, collateralAmount])),
376
- )
377
- .readFrom([iAsset.utxo, gov, cdpScriptRefUtxo])
378
- .addSignerKey(pkh.hash);
379
- if (!cdp.datum) throw new Error('Unable to find CDP Datum');
380
- const cdpD = parseCDPDatum(cdp.datum);
381
-
382
- if (!('ActiveCDPInterestTracking' in cdpD.cdpFees))
383
- throw new Error('Invalid CDP Fees');
384
-
385
- const newSnapshot =
386
- calculateUnitaryInterestSinceOracleLastUpdated(
387
- BigInt(now),
388
- interestOracleDatum,
389
- ) + interestOracleDatum.unitaryInterest;
390
-
391
- const cdpD_: CDPContent = {
392
- ...cdpD,
393
- mintedAmt: cdpD.mintedAmt + mintAmount,
394
- cdpFees: {
395
- ActiveCDPInterestTracking: {
396
- lastSettled: BigInt(now),
397
- unitaryInterestSnapshot: newSnapshot,
398
- },
399
- },
400
- };
401
-
402
- tx.pay.ToContract(
403
- cdp.address,
404
- {
405
- kind: 'inline',
406
- value: serialiseCDPDatum(cdpD_),
407
- },
408
- cdpAssets,
409
- );
410
-
411
- // Find Oracle Ref Input
412
- const oracleAsset = iAsset.datum.price;
413
- if (!('Oracle' in oracleAsset)) throw new Error('Invalid oracle asset');
414
- const oracleRefInput = priceOracleRef
415
- ? (await lucid.utxosByOutRef([priceOracleRef]))[0]
416
- : await lucid.utxoByUnit(
417
- oracleAsset.Oracle.oracleNft.asset.currencySymbol +
418
- fromText(oracleAsset.Oracle.oracleNft.asset.tokenName),
419
- );
420
-
421
- // Fail if delisted asset
422
- if (!oracleRefInput.datum)
423
- return Promise.reject(new Error('Invalid oracle input'));
424
- const od = parsePriceOracleDatum(oracleRefInput.datum);
425
- if (!od) return Promise.reject(new Error('Invalid oracle input'));
426
-
427
- // TODO: Sanity check: oacle expiration
428
- // Oracle timestamp - 20s (length of a slot)
429
- // Oracle timestamp - 20s (length of a slot)
430
- const cappedValidateTo = od.expiration - 20_001n;
431
- const timeValidFrom = now - 1_000;
432
- const timeValidTo_ = now + Number(params.cdpCreatorParams.biasTime) - 1_000;
433
- const timeValidTo =
434
- cappedValidateTo <= timeValidFrom
435
- ? timeValidTo_
436
- : Math.min(timeValidTo_, Number(cappedValidateTo));
437
- tx.readFrom([oracleRefInput])
438
- .validFrom(Number(timeValidFrom))
439
- .validTo(Number(timeValidTo));
440
-
441
- let fee = 0n;
442
- if (collateralAmount < 0) {
443
- fee += calculateFeeFromPercentage(
444
- govData.protocolParams.collateralFeePercentage.getOnChainInt,
445
- collateralAmount,
446
- );
447
- }
448
-
449
- if (mintAmount > 0) {
450
- fee += calculateFeeFromPercentage(
451
- iAsset.datum.debtMintingFeePercentage.getOnChainInt,
452
- (mintAmount * od.price.getOnChainInt) / 1_000_000n,
453
- );
454
- }
455
-
456
- // Interest payment
457
-
458
- const interestPaymentAsset = calculateAccruedInterest(
459
- BigInt(now),
460
- cdpD.cdpFees.ActiveCDPInterestTracking.unitaryInterestSnapshot,
461
- cdpD.mintedAmt,
462
- cdpD.cdpFees.ActiveCDPInterestTracking.lastSettled,
463
- interestOracleDatum,
464
- );
465
- const interestPayment =
466
- (interestPaymentAsset * od.price.getOnChainInt) / 1_000_000n;
467
- const interestCollectorPayment = calculateFeeFromPercentage(
468
- iAsset.datum.interestCollectorPortionPercentage.getOnChainInt,
469
- interestPayment,
470
- );
471
- const interestTreasuryPayment = interestPayment - interestCollectorPayment;
472
-
473
- if (interestTreasuryPayment > 0) {
474
- await TreasuryContract.feeTx(
475
- interestTreasuryPayment,
476
- lucid,
477
- params,
478
- tx,
479
- treasuryRef,
480
- );
481
- }
482
-
483
- fee += interestCollectorPayment;
484
- tx.readFrom([interestOracleOut]);
485
-
486
- if (mintAmount !== 0n) {
487
- const iAssetTokenScriptRefUtxo = await CDPContract.assetTokenRef(
488
- params.scriptReferences,
489
- lucid,
490
- );
491
- const iassetToken =
492
- params.cdpParams.cdpAssetSymbol.unCurrencySymbol + cdpD.iasset;
493
- const mintValue = {} as Assets;
494
- mintValue[iassetToken] = mintAmount;
495
-
496
- tx.readFrom([iAssetTokenScriptRefUtxo]).mintAssets(
497
- mintValue,
498
- Data.to(new Constr(0, [])),
499
- );
500
- }
501
-
502
- if (fee > 0n) {
503
- await CollectorContract.feeTx(fee, lucid, params, tx, collectorRef);
504
- }
505
-
506
- return tx;
507
- }
508
-
509
- static async close(
510
- cdpRef: OutRef,
511
- params: SystemParams,
512
- lucid: LucidEvolution,
513
- assetRef?: OutRef,
514
- priceOracleRef?: OutRef,
515
- interestOracleRef?: OutRef,
516
- collectorRef?: OutRef,
517
- govRef?: OutRef,
518
- treasuryRef?: OutRef,
519
- ): Promise<TxBuilder> {
520
- // Find Pkh, Skh
521
- const [pkh, _] = await addrDetails(lucid);
522
- const now = Date.now();
523
-
524
- // Find Outputs: iAsset Output, CDP Output, Gov Output
525
- const cdp = (await lucid.utxosByOutRef([cdpRef]))[0];
526
- if (!cdp.datum) throw new Error('Unable to find CDP Datum');
527
- const cdpDatum = parseCDPDatum(cdp.datum);
528
- const iAsset = await (assetRef
529
- ? IAssetHelpers.findIAssetByRef(assetRef, lucid)
530
- : IAssetHelpers.findIAssetByName(cdpDatum.iasset, params, lucid));
531
-
532
- const gov = govRef
533
- ? (await lucid.utxosByOutRef([govRef]))[0]
534
- : await lucid.utxoByUnit(
535
- params.govParams.govNFT[0].unCurrencySymbol +
536
- fromText(params.govParams.govNFT[1].unTokenName),
537
- );
538
-
539
- if (!gov.datum) throw new Error('Unable to find Gov Datum');
540
- const cdpScriptRefUtxo = await CDPContract.scriptRef(
541
- params.scriptReferences,
542
- lucid,
543
- );
544
-
545
- const interestOracleAsset = iAsset.datum.interestOracleNft;
546
- const interestOracleOut = interestOracleRef
547
- ? (await lucid.utxosByOutRef([interestOracleRef]))[0]
548
- : await lucid.utxoByUnit(
549
- interestOracleAsset.currencySymbol +
550
- fromText(interestOracleAsset.tokenName),
551
- );
552
- if (!interestOracleOut.datum)
553
- return Promise.reject(new Error('Interest Oracle datum not found'));
554
- const interestOracleDatum = parseInterestOracleDatum(
555
- interestOracleOut.datum,
556
- );
557
-
558
- const tx = lucid
559
- .newTx()
560
- .collectFrom([cdp], Data.to(new Constr(1, [BigInt(now)])))
561
- .readFrom([iAsset.utxo, gov, cdpScriptRefUtxo])
562
- .addSignerKey(pkh.hash);
563
- if (!cdp.datum) throw new Error('Unable to find CDP Datum');
564
- const cdpD = parseCDPDatum(cdp.datum);
565
- if (!('ActiveCDPInterestTracking' in cdpD.cdpFees))
566
- throw new Error('Invalid CDP Fees');
567
-
568
- // Find Oracle Ref Input
569
- if (!('Oracle' in iAsset.datum.price))
570
- throw new Error('iAsset is delisted');
571
- const oracleAsset = iAsset.datum.price.Oracle.oracleNft.asset;
572
- const oracleRefInput = priceOracleRef
573
- ? (await lucid.utxosByOutRef([priceOracleRef]))[0]
574
- : await lucid.utxoByUnit(
575
- oracleAsset.currencySymbol + fromText(oracleAsset.tokenName),
576
- );
577
-
578
- // Fail if delisted asset
579
- if (!oracleRefInput.datum)
580
- return Promise.reject(new Error('Invalid oracle input'));
581
- const od = parsePriceOracleDatum(oracleRefInput.datum);
582
-
583
- // TODO: Sanity check: oacle expiration
584
- // Oracle timestamp - 20s (length of a slot)
585
- // Oracle timestamp - 20s (length of a slot)
586
- const cappedValidateTo = od.expiration - 20_001n;
587
- const timeValidFrom = now - 1_000;
588
- const timeValidTo_ = now + Number(params.cdpCreatorParams.biasTime) - 1_000;
589
- const timeValidTo =
590
- cappedValidateTo <= timeValidFrom
591
- ? timeValidTo_
592
- : Math.min(timeValidTo_, Number(cappedValidateTo));
593
- tx.readFrom([oracleRefInput])
594
- .validFrom(Number(timeValidFrom))
595
- .validTo(Number(timeValidTo));
596
-
597
- let fee = 0n;
598
-
599
- // Interest payment
600
- const interestPaymentAsset = calculateAccruedInterest(
601
- BigInt(now),
602
- cdpD.cdpFees.ActiveCDPInterestTracking.unitaryInterestSnapshot,
603
- cdpD.mintedAmt,
604
- cdpD.cdpFees.ActiveCDPInterestTracking.lastSettled,
605
- interestOracleDatum,
606
- );
607
- const interestPayment =
608
- (interestPaymentAsset * od.price.getOnChainInt) / 1_000_000n;
609
- const interestCollectorPayment = calculateFeeFromPercentage(
610
- iAsset.datum.interestCollectorPortionPercentage.getOnChainInt,
611
- interestPayment,
612
- );
613
- const interestTreasuryPayment = interestPayment - interestCollectorPayment;
614
-
615
- if (interestTreasuryPayment > 0) {
616
- await TreasuryContract.feeTx(
617
- interestTreasuryPayment,
618
- lucid,
619
- params,
620
- tx,
621
- treasuryRef,
622
- );
623
- }
624
-
625
- fee += interestCollectorPayment;
626
- tx.readFrom([interestOracleOut]);
627
-
628
- const iAssetTokenScriptRefUtxo = await CDPContract.assetTokenRef(
629
- params.scriptReferences,
630
- lucid,
631
- );
632
- const iassetToken =
633
- params.cdpParams.cdpAssetSymbol.unCurrencySymbol + cdpD.iasset;
634
- const assetBurnValue = {} as Assets;
635
- assetBurnValue[iassetToken] = -BigInt(cdpD.mintedAmt);
636
- const cdpTokenBurnValue = {} as Assets;
637
- cdpTokenBurnValue[
638
- params.cdpParams.cdpAuthToken[0].unCurrencySymbol +
639
- fromText(params.cdpParams.cdpAuthToken[1].unTokenName)
640
- ] = -1n;
641
- const cdpAuthTokenScriptRefUtxo = await CDPContract.cdpAuthTokenRef(
642
- params.scriptReferences,
643
- lucid,
644
- );
645
- tx.readFrom([iAssetTokenScriptRefUtxo])
646
- .mintAssets(assetBurnValue, Data.to(new Constr(0, [])))
647
- .readFrom([cdpAuthTokenScriptRefUtxo])
648
- .mintAssets(cdpTokenBurnValue, Data.to(new Constr(0, [])));
649
-
650
- if (fee > 0n) {
651
- await CollectorContract.feeTx(fee, lucid, params, tx, collectorRef);
652
- }
653
-
654
- return tx;
655
- }
656
-
657
- static validator(params: CdpParams): SpendingValidator {
658
- return {
659
- type: _cdpValidator.type,
660
- script: applyParamsToScript(_cdpValidator.cborHex, [
661
- new Constr(0, [
662
- new Constr(0, [
663
- params.cdpAuthToken[0].unCurrencySymbol,
664
- fromText(params.cdpAuthToken[1].unTokenName),
665
- ]),
666
- params.cdpAssetSymbol.unCurrencySymbol,
667
- new Constr(0, [
668
- params.iAssetAuthToken[0].unCurrencySymbol,
669
- fromText(params.iAssetAuthToken[1].unTokenName),
670
- ]),
671
- new Constr(0, [
672
- params.stabilityPoolAuthToken[0].unCurrencySymbol,
673
- fromText(params.stabilityPoolAuthToken[1].unTokenName),
674
- ]),
675
- new Constr(0, [
676
- params.versionRecordToken[0].unCurrencySymbol,
677
- fromText(params.versionRecordToken[1].unTokenName),
678
- ]),
679
- new Constr(0, [
680
- params.upgradeToken[0].unCurrencySymbol,
681
- fromText(params.upgradeToken[1].unTokenName),
682
- ]),
683
- params.collectorValHash,
684
- params.spValHash,
685
- new Constr(0, [
686
- params.govNFT[0].unCurrencySymbol,
687
- fromText(params.govNFT[1].unTokenName),
688
- ]),
689
- BigInt(params.minCollateralInLovelace),
690
- BigInt(params.partialRedemptionExtraFeeLovelace),
691
- BigInt(params.biasTime),
692
- params.treasuryValHash,
693
- ]),
694
- ]),
695
- };
696
- }
697
-
698
- static validatorHash(params: CdpParams): string {
699
- return validatorToScriptHash(CDPContract.validator(params));
700
- }
701
-
702
- static address(
703
- cdpParams: CdpParams,
704
- lucid: LucidEvolution,
705
- skh?: Credential,
706
- ) {
707
- const network = lucid.config().network;
708
- if (!network) {
709
- throw new Error('Network configuration is undefined');
710
- }
711
- return validatorToAddress(network, CDPContract.validator(cdpParams), skh);
712
- }
713
-
714
- static scriptRef(
715
- params: ScriptReferences,
716
- lucid: LucidEvolution,
717
- ): Promise<UTxO> {
718
- return scriptRef(params.cdpValidatorRef, lucid);
719
- }
720
-
721
- static cdpAuthTokenRef(
722
- params: ScriptReferences,
723
- lucid: LucidEvolution,
724
- ): Promise<UTxO> {
725
- return scriptRef(params.authTokenPolicies.cdpAuthTokenRef, lucid);
726
- }
727
-
728
- static assetTokenRef(
729
- params: ScriptReferences,
730
- lucid: LucidEvolution,
731
- ): Promise<UTxO> {
732
- return scriptRef(params.iAssetTokenPolicyRef, lucid);
733
- }
734
-
735
- static assetAuthTokenRef(
736
- params: ScriptReferences,
737
- lucid: LucidEvolution,
738
- ): Promise<UTxO> {
739
- return scriptRef(params.authTokenPolicies.iAssetTokenRef, lucid);
740
- }
741
- }