@indigo-labs/indigo-sdk 0.1.20 → 0.1.22

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 (135) hide show
  1. package/.github/workflows/ci.yml +3 -8
  2. package/.github/workflows/test.yml +44 -0
  3. package/dist/index.d.mts +678 -1001
  4. package/dist/index.d.ts +678 -1001
  5. package/dist/index.js +2272 -4670
  6. package/dist/index.mjs +2234 -4618
  7. package/eslint.config.mjs +1 -7
  8. package/package.json +4 -9
  9. package/src/contracts/cdp.ts +746 -0
  10. package/src/contracts/collector.ts +98 -0
  11. package/src/contracts/gov.ts +1 -0
  12. package/src/contracts/interest-oracle.ts +149 -0
  13. package/src/contracts/{lrp/transactions.ts → lrp.ts} +14 -14
  14. package/src/contracts/{one-shot/transactions.ts → one-shot.ts} +3 -3
  15. package/src/contracts/stability-pool.ts +690 -0
  16. package/src/contracts/staking.ts +348 -0
  17. package/src/contracts/treasury.ts +112 -0
  18. package/src/helpers/asset-helpers.ts +57 -0
  19. package/src/{utils → helpers}/helper-txs.ts +0 -1
  20. package/src/{utils/utils.ts → helpers/helpers.ts} +10 -0
  21. package/src/{contracts/interest-oracle/helpers.ts → helpers/interest-oracle.ts} +9 -37
  22. package/src/{contracts/stability-pool/helpers.ts → helpers/stability-pool-helpers.ts} +6 -110
  23. package/src/helpers/staking-helpers.ts +94 -0
  24. package/src/helpers/time-helpers.ts +4 -0
  25. package/src/{utils → helpers}/value-helpers.ts +0 -10
  26. package/src/index.ts +33 -37
  27. package/src/{validators → scripts}/cdp-creator-validator.ts +50 -4
  28. package/src/{validators → scripts}/cdp-validator.ts +5 -3
  29. package/src/{validators → scripts}/collector-validator.ts +3 -2
  30. package/src/scripts/execute-validator.ts +52 -0
  31. package/src/{validators/governance-validator.ts → scripts/gov-validator.ts} +40 -3
  32. package/src/{validators → scripts}/interest-oracle-validator.ts +20 -4
  33. package/src/scripts/lrp-validator.ts +40 -0
  34. package/src/{contracts/one-shot/scripts.ts → scripts/one-shot-policy.ts} +1 -1
  35. package/src/scripts/poll-manager-validator.ts +52 -0
  36. package/src/{validators → scripts}/poll-shard-validator.ts +43 -3
  37. package/src/{contracts/price-oracle/scripts.ts → scripts/price-oracle-validator.ts} +4 -1
  38. package/src/{validators → scripts}/stability-pool-validator.ts +57 -4
  39. package/src/{validators → scripts}/staking-validator.ts +3 -2
  40. package/src/{validators → scripts}/treasury-validator.ts +3 -2
  41. package/src/{validators → scripts}/version-record-policy.ts +23 -4
  42. package/src/{validators/execute-validator.ts → scripts/version-registry.ts} +11 -3
  43. package/src/types/generic.ts +60 -78
  44. package/src/{contracts/cdp-creator/types.ts → types/indigo/cdp-creator.ts} +4 -6
  45. package/src/types/indigo/cdp.ts +88 -0
  46. package/src/types/indigo/execute.ts +21 -0
  47. package/src/types/indigo/gov.ts +51 -0
  48. package/src/{contracts/interest-oracle/types.ts → types/indigo/interest-oracle.ts} +1 -1
  49. package/src/{contracts/lrp/types.ts → types/indigo/lrp.ts} +2 -2
  50. package/src/types/indigo/poll-manager.ts +21 -0
  51. package/src/types/indigo/poll-shard.ts +16 -0
  52. package/src/{contracts/price-oracle/types.ts → types/indigo/price-oracle.ts} +4 -16
  53. package/src/types/indigo/stability-pool.ts +233 -0
  54. package/src/types/indigo/staking.ts +99 -0
  55. package/src/{contracts/version-registry/types.ts → types/indigo/version-record.ts} +1 -1
  56. package/src/types/on-chain-decimal.ts +0 -22
  57. package/src/types/system-params.ts +11 -22
  58. package/tests/datums.test.ts +108 -125
  59. package/tests/endpoints/initialize.ts +338 -240
  60. package/tests/hash-checks.test.ts +21 -26
  61. package/tests/indigo-test-helpers.ts +55 -1
  62. package/tests/initialize.test.ts +5 -10
  63. package/tests/interest-calculations.test.ts +18 -18
  64. package/tests/interest-oracle.test.ts +18 -20
  65. package/tests/lrp.test.ts +65 -191
  66. package/tests/queries/governance-queries.ts +16 -19
  67. package/tests/queries/iasset-queries.ts +23 -46
  68. package/tests/queries/interest-oracle-queries.ts +6 -3
  69. package/tests/queries/lrp-queries.ts +2 -2
  70. package/tests/queries/price-oracle-queries.ts +22 -5
  71. package/tests/queries/stability-pool-queries.ts +8 -10
  72. package/tests/queries/staking-queries.ts +19 -28
  73. package/tests/stability-pool.test.ts +71 -186
  74. package/tests/staking.test.ts +23 -30
  75. package/tests/test-helpers.ts +2 -11
  76. package/tsconfig.json +1 -3
  77. package/vitest.config.ts +1 -1
  78. package/src/contracts/cdp/helpers.ts +0 -167
  79. package/src/contracts/cdp/scripts.ts +0 -33
  80. package/src/contracts/cdp/transactions.ts +0 -1310
  81. package/src/contracts/cdp/types.ts +0 -161
  82. package/src/contracts/cdp-creator/scripts.ts +0 -39
  83. package/src/contracts/collector/scripts.ts +0 -32
  84. package/src/contracts/collector/transactions.ts +0 -44
  85. package/src/contracts/execute/scripts.ts +0 -48
  86. package/src/contracts/execute/types.ts +0 -57
  87. package/src/contracts/gov/helpers.ts +0 -157
  88. package/src/contracts/gov/scripts.ts +0 -34
  89. package/src/contracts/gov/transactions.ts +0 -1224
  90. package/src/contracts/gov/types-new.ts +0 -115
  91. package/src/contracts/gov/types.ts +0 -89
  92. package/src/contracts/interest-oracle/scripts.ts +0 -18
  93. package/src/contracts/interest-oracle/transactions.ts +0 -149
  94. package/src/contracts/lrp/scripts.ts +0 -27
  95. package/src/contracts/poll/helpers.ts +0 -55
  96. package/src/contracts/poll/scripts.ts +0 -72
  97. package/src/contracts/poll/types-poll-manager.ts +0 -38
  98. package/src/contracts/poll/types-poll-shard.ts +0 -38
  99. package/src/contracts/poll/types-poll.ts +0 -88
  100. package/src/contracts/price-oracle/transactions.ts +0 -112
  101. package/src/contracts/stability-pool/scripts.ts +0 -46
  102. package/src/contracts/stability-pool/transactions.ts +0 -660
  103. package/src/contracts/stability-pool/types-new.ts +0 -208
  104. package/src/contracts/stability-pool/types.ts +0 -42
  105. package/src/contracts/staking/helpers.ts +0 -116
  106. package/src/contracts/staking/scripts.ts +0 -41
  107. package/src/contracts/staking/transactions.ts +0 -268
  108. package/src/contracts/staking/types-new.ts +0 -81
  109. package/src/contracts/staking/types.ts +0 -41
  110. package/src/contracts/treasury/scripts.ts +0 -37
  111. package/src/contracts/treasury/transactions.ts +0 -44
  112. package/src/contracts/treasury/types.ts +0 -55
  113. package/src/contracts/version-registry/scripts.ts +0 -29
  114. package/src/contracts/version-registry/types-new.ts +0 -19
  115. package/src/contracts/vesting/helpers.ts +0 -267
  116. package/src/types/evolution-schema-options.ts +0 -16
  117. package/src/utils/bigint-utils.ts +0 -7
  118. package/src/utils/time-helpers.ts +0 -4
  119. package/src/validators/lrp-validator.ts +0 -7
  120. package/src/validators/poll-manager-validator.ts +0 -7
  121. package/src/validators/version-registry-validator.ts +0 -7
  122. package/tests/cdp.test.ts +0 -1565
  123. package/tests/gov.test.ts +0 -1874
  124. package/tests/mock/assets-mock.ts +0 -59
  125. package/tests/queries/cdp-queries.ts +0 -144
  126. package/tests/queries/collector-queries.ts +0 -26
  127. package/tests/queries/execute-queries.ts +0 -46
  128. package/tests/queries/poll-queries.ts +0 -97
  129. package/tests/queries/treasury-queries.ts +0 -19
  130. package/tests/utils/asserts.ts +0 -13
  131. package/tests/utils/index.ts +0 -50
  132. /package/src/{utils → helpers}/indigo-helpers.ts +0 -0
  133. /package/src/{utils → helpers}/lucid-utils.ts +0 -0
  134. /package/src/{contracts/price-oracle/helpers.ts → helpers/price-oracle-helpers.ts} +0 -0
  135. /package/src/{contracts/one-shot/types.ts → types/one-shot.ts} +0 -0
@@ -0,0 +1,690 @@
1
+ import {
2
+ Constr,
3
+ fromText,
4
+ LucidEvolution,
5
+ TxBuilder,
6
+ validatorToScriptHash,
7
+ Data,
8
+ UTxO,
9
+ credentialToAddress,
10
+ } from '@lucid-evolution/lucid';
11
+ import {
12
+ EpochToScaleToSum,
13
+ mkSPInteger,
14
+ parseAccountDatum,
15
+ parseStabilityPoolDatum,
16
+ serialiseStabilityPoolDatum,
17
+ serialiseStabilityPoolRedeemer,
18
+ spDiv,
19
+ spMul,
20
+ StabilityPoolDatum,
21
+ StabilityPoolRedeemer,
22
+ StabilityPoolSnapshot,
23
+ AccountAction,
24
+ AccountContent,
25
+ spAdd,
26
+ fromSPInteger,
27
+ ActionReturnDatum,
28
+ spSub,
29
+ } from '../types/indigo/stability-pool';
30
+ import { SystemParams } from '../types/system-params';
31
+ import { addrDetails, scriptRef } from '../helpers/lucid-utils';
32
+ import { mkStabilityPoolValidatorFromSP } from '../scripts/stability-pool-validator';
33
+ import {
34
+ adjustmentHelper,
35
+ setSumInEpochToScaleToSum,
36
+ updatePoolSnapshotWithdrawalFee,
37
+ } from '../helpers/stability-pool-helpers';
38
+ import { calculateFeeFromPercentage } from '../helpers/indigo-helpers';
39
+ import { GovDatum, parseGovDatum } from '../types/indigo/gov';
40
+ import { IAssetContent, parseIAssetDatum } from '../types/indigo/cdp';
41
+ import { CollectorContract } from './collector';
42
+ import { addressFromBech32, addressToBech32 } from '../types/generic';
43
+
44
+ export class StabilityPoolContract {
45
+ static async createAccount(
46
+ asset: string,
47
+ amount: bigint,
48
+ params: SystemParams,
49
+ lucid: LucidEvolution,
50
+ ): Promise<TxBuilder> {
51
+ const [pkh, _skh] = await addrDetails(lucid);
52
+ const minLovelaces = BigInt(
53
+ params.stabilityPoolParams.accountCreateFeeLovelaces +
54
+ params.stabilityPoolParams.requestCollateralLovelaces,
55
+ );
56
+ const datum: StabilityPoolDatum = {
57
+ Account: {
58
+ content: {
59
+ owner: pkh.hash,
60
+ asset: fromText(asset),
61
+ snapshot: {
62
+ productVal: { value: 0n },
63
+ depositVal: { value: 0n },
64
+ sumVal: { value: 0n },
65
+ epoch: 0n,
66
+ scale: 0n,
67
+ },
68
+ request: 'Create',
69
+ },
70
+ },
71
+ };
72
+
73
+ return lucid
74
+ .newTx()
75
+ .pay.ToContract(
76
+ credentialToAddress(lucid.config().network, {
77
+ hash: validatorToScriptHash(
78
+ mkStabilityPoolValidatorFromSP(params.stabilityPoolParams),
79
+ ),
80
+ type: 'Script',
81
+ }),
82
+ { kind: 'inline', value: serialiseStabilityPoolDatum(datum) },
83
+ {
84
+ lovelace: minLovelaces,
85
+ [params.stabilityPoolParams.assetSymbol.unCurrencySymbol +
86
+ fromText(asset)]: amount,
87
+ },
88
+ )
89
+ .addSignerKey(pkh.hash);
90
+ }
91
+
92
+ static async adjustAccount(
93
+ asset: string,
94
+ amount: bigint,
95
+ accountUtxo: UTxO,
96
+ params: SystemParams,
97
+ lucid: LucidEvolution,
98
+ ): Promise<TxBuilder> {
99
+ const myAddress = await lucid.wallet().address();
100
+
101
+ const stabilityPoolScriptRef = await scriptRef(
102
+ params.scriptReferences.stabilityPoolValidatorRef,
103
+ lucid,
104
+ );
105
+
106
+ const request: AccountAction = {
107
+ Adjust: {
108
+ amount: amount,
109
+ outputAddress: addressFromBech32(myAddress),
110
+ },
111
+ };
112
+ const oldAccountDatum: AccountContent = parseAccountDatum(
113
+ accountUtxo.datum,
114
+ );
115
+
116
+ const newAccountDatum: AccountContent = {
117
+ ...oldAccountDatum,
118
+ request,
119
+ };
120
+
121
+ const redeemer: StabilityPoolRedeemer = {
122
+ RequestAction: {
123
+ action: request,
124
+ },
125
+ };
126
+
127
+ const value = {
128
+ lovelace: BigInt(
129
+ params.stabilityPoolParams.requestCollateralLovelaces +
130
+ params.stabilityPoolParams.accountAdjustmentFeeLovelaces,
131
+ ),
132
+ [params.stabilityPoolParams.accountToken[0].unCurrencySymbol +
133
+ fromText(params.stabilityPoolParams.accountToken[1].unTokenName)]: 1n,
134
+ };
135
+
136
+ if (amount > 0n) {
137
+ value[
138
+ params.stabilityPoolParams.assetSymbol.unCurrencySymbol +
139
+ fromText(asset)
140
+ ] = amount;
141
+ }
142
+
143
+ return lucid
144
+ .newTx()
145
+ .readFrom([stabilityPoolScriptRef])
146
+ .collectFrom([accountUtxo], serialiseStabilityPoolRedeemer(redeemer))
147
+ .pay.ToContract(
148
+ credentialToAddress(lucid.config().network, {
149
+ hash: validatorToScriptHash(
150
+ mkStabilityPoolValidatorFromSP(params.stabilityPoolParams),
151
+ ),
152
+ type: 'Script',
153
+ }),
154
+ {
155
+ kind: 'inline',
156
+ value: serialiseStabilityPoolDatum({
157
+ Account: {
158
+ content: newAccountDatum,
159
+ },
160
+ }),
161
+ },
162
+ value,
163
+ )
164
+ .addSignerKey(oldAccountDatum.owner);
165
+ }
166
+
167
+ static async closeAccount(
168
+ accountUtxo: UTxO,
169
+ params: SystemParams,
170
+ lucid: LucidEvolution,
171
+ ): Promise<TxBuilder> {
172
+ const myAddress = await lucid.wallet().address();
173
+
174
+ const stabilityPoolScriptRef = await scriptRef(
175
+ params.scriptReferences.stabilityPoolValidatorRef,
176
+ lucid,
177
+ );
178
+
179
+ const request: AccountAction = {
180
+ Close: {
181
+ outputAddress: addressFromBech32(myAddress),
182
+ },
183
+ };
184
+ const oldAccountDatum: AccountContent = parseAccountDatum(
185
+ accountUtxo.datum,
186
+ );
187
+ const newAccountDatum: AccountContent = {
188
+ ...oldAccountDatum,
189
+ request,
190
+ };
191
+
192
+ const redeemer: StabilityPoolRedeemer = {
193
+ RequestAction: {
194
+ action: request,
195
+ },
196
+ };
197
+
198
+ return lucid
199
+ .newTx()
200
+ .readFrom([stabilityPoolScriptRef])
201
+ .collectFrom([accountUtxo], serialiseStabilityPoolRedeemer(redeemer))
202
+ .pay.ToContract(
203
+ credentialToAddress(lucid.config().network, {
204
+ hash: validatorToScriptHash(
205
+ mkStabilityPoolValidatorFromSP(params.stabilityPoolParams),
206
+ ),
207
+ type: 'Script',
208
+ }),
209
+ {
210
+ kind: 'inline',
211
+ value: serialiseStabilityPoolDatum({
212
+ Account: {
213
+ content: newAccountDatum,
214
+ },
215
+ }),
216
+ },
217
+ {
218
+ lovelace: BigInt(
219
+ params.stabilityPoolParams.requestCollateralLovelaces +
220
+ params.stabilityPoolParams.accountAdjustmentFeeLovelaces,
221
+ ),
222
+ [params.stabilityPoolParams.accountToken[0].unCurrencySymbol +
223
+ fromText(params.stabilityPoolParams.accountToken[1].unTokenName)]: 1n,
224
+ },
225
+ )
226
+ .addSignerKey(oldAccountDatum.owner);
227
+ }
228
+
229
+ static async processRequest(
230
+ asset: string,
231
+ stabilityPoolUtxo: UTxO,
232
+ accountUtxo: UTxO,
233
+ govUtxo: UTxO,
234
+ iAssetUtxo: UTxO,
235
+ newSnapshotUtxo: UTxO | undefined,
236
+ params: SystemParams,
237
+ lucid: LucidEvolution,
238
+ ): Promise<TxBuilder> {
239
+ const redeemer: StabilityPoolRedeemer = {
240
+ ProcessRequest: {
241
+ requestRef: {
242
+ txHash: { hash: accountUtxo.txHash },
243
+ outputIndex: BigInt(accountUtxo.outputIndex),
244
+ },
245
+ },
246
+ };
247
+ const stabilityPoolScriptRef = await scriptRef(
248
+ params.scriptReferences.stabilityPoolValidatorRef,
249
+ lucid,
250
+ );
251
+
252
+ const accountDatum = parseAccountDatum(accountUtxo.datum);
253
+ const stabilityPoolDatum = parseStabilityPoolDatum(stabilityPoolUtxo.datum);
254
+
255
+ const tx = lucid
256
+ .newTx()
257
+ .collectFrom(
258
+ [stabilityPoolUtxo],
259
+ serialiseStabilityPoolRedeemer(redeemer),
260
+ )
261
+ .collectFrom([accountUtxo], serialiseStabilityPoolRedeemer(redeemer))
262
+ .readFrom([iAssetUtxo, govUtxo, stabilityPoolScriptRef]);
263
+
264
+ if (!accountDatum.request) throw new Error('Account Request is null');
265
+ if (accountDatum.request === 'Create') {
266
+ const accountTokenScriptRef = await scriptRef(
267
+ params.scriptReferences.authTokenPolicies.accountTokenRef,
268
+ lucid,
269
+ );
270
+ tx.readFrom([accountTokenScriptRef]);
271
+
272
+ const iassetUnit =
273
+ params.stabilityPoolParams.assetSymbol.unCurrencySymbol +
274
+ fromText(asset);
275
+ const reqAmount = accountUtxo.assets[iassetUnit] ?? 0n;
276
+
277
+ const newAccountSnapshot: StabilityPoolSnapshot = {
278
+ ...stabilityPoolDatum.snapshot,
279
+ depositVal: {
280
+ value: spAdd(accountDatum.snapshot.depositVal, mkSPInteger(reqAmount))
281
+ .value,
282
+ },
283
+ };
284
+
285
+ const newDeposit = spAdd(
286
+ stabilityPoolDatum.snapshot.depositVal,
287
+ mkSPInteger(reqAmount),
288
+ );
289
+ const newSum = spAdd(
290
+ stabilityPoolDatum.snapshot.sumVal,
291
+ spDiv(
292
+ spMul(
293
+ mkSPInteger(
294
+ BigInt(params.stabilityPoolParams.accountCreateFeeLovelaces),
295
+ ),
296
+ stabilityPoolDatum.snapshot.productVal,
297
+ ),
298
+ newDeposit,
299
+ ),
300
+ );
301
+ const newStabilityPoolSnapshot: StabilityPoolSnapshot = {
302
+ ...stabilityPoolDatum.snapshot,
303
+ depositVal: newDeposit,
304
+ sumVal: newSum,
305
+ };
306
+
307
+ const newEpochToScaleToSum: EpochToScaleToSum = new Map(
308
+ stabilityPoolDatum.epochToScaleToSum,
309
+ );
310
+ newEpochToScaleToSum.set(
311
+ {
312
+ epoch: stabilityPoolDatum.snapshot.epoch,
313
+ scale: stabilityPoolDatum.snapshot.scale,
314
+ },
315
+ newSum,
316
+ );
317
+
318
+ const stabilityPoolAssetToken =
319
+ stabilityPoolUtxo.assets[iassetUnit] ?? 0n;
320
+ const poolOutputValue = {
321
+ lovelace:
322
+ stabilityPoolUtxo.assets.lovelace +
323
+ BigInt(params.stabilityPoolParams.accountCreateFeeLovelaces),
324
+ [params.stabilityPoolParams.stabilityPoolToken[0].unCurrencySymbol +
325
+ fromText(params.stabilityPoolParams.stabilityPoolToken[1].unTokenName)]:
326
+ 1n,
327
+ [params.stabilityPoolParams.assetSymbol.unCurrencySymbol +
328
+ fromText(asset)]: stabilityPoolAssetToken + reqAmount,
329
+ };
330
+
331
+ tx.mintAssets(
332
+ {
333
+ [params.stabilityPoolParams.accountToken[0].unCurrencySymbol +
334
+ fromText(params.stabilityPoolParams.accountToken[1].unTokenName)]: 1n,
335
+ },
336
+ Data.to(new Constr(0, [])),
337
+ );
338
+
339
+ tx.pay.ToContract(
340
+ stabilityPoolUtxo.address,
341
+ {
342
+ kind: 'inline',
343
+ value: serialiseStabilityPoolDatum({
344
+ StabilityPool: {
345
+ content: {
346
+ ...stabilityPoolDatum,
347
+ snapshot: newStabilityPoolSnapshot,
348
+ epochToScaleToSum: newEpochToScaleToSum,
349
+ },
350
+ },
351
+ }),
352
+ },
353
+ poolOutputValue,
354
+ );
355
+
356
+ tx.pay.ToContract(
357
+ stabilityPoolUtxo.address,
358
+ {
359
+ kind: 'inline',
360
+ value: serialiseStabilityPoolDatum({
361
+ Account: {
362
+ content: {
363
+ ...accountDatum,
364
+ snapshot: newAccountSnapshot,
365
+ request: null,
366
+ },
367
+ },
368
+ }),
369
+ },
370
+ {
371
+ lovelace:
372
+ accountUtxo.assets.lovelace -
373
+ BigInt(params.stabilityPoolParams.accountCreateFeeLovelaces),
374
+ [params.stabilityPoolParams.accountToken[0].unCurrencySymbol +
375
+ fromText(params.stabilityPoolParams.accountToken[1].unTokenName)]: 1n,
376
+ },
377
+ );
378
+ } else if ('Adjust' in accountDatum.request) {
379
+ const amount = accountDatum.request.Adjust.amount;
380
+ const outputAddress = addressToBech32(
381
+ lucid,
382
+ accountDatum.request.Adjust.outputAddress,
383
+ );
384
+ const myAddress = await lucid.wallet().address();
385
+
386
+ const [updatedAccountSnapshot, reward, refInputs] = adjustmentHelper(
387
+ stabilityPoolUtxo,
388
+ newSnapshotUtxo,
389
+ stabilityPoolDatum.snapshot,
390
+ stabilityPoolDatum.epochToScaleToSum,
391
+ accountDatum.snapshot,
392
+ );
393
+
394
+ const govDatum: GovDatum = parseGovDatum(govUtxo.datum);
395
+ const iassetDatum: IAssetContent = parseIAssetDatum(iAssetUtxo.datum);
396
+ const rewardLovelacesFee = calculateFeeFromPercentage(
397
+ govDatum.protocolParams.collateralFeePercentage,
398
+ reward,
399
+ );
400
+ const isDepositOrRewardWithdrawal: boolean = amount > 0n;
401
+ const bigIntMax = (...args: bigint[]): bigint =>
402
+ args.reduce((m, e) => (e > m ? e : m));
403
+
404
+ const balanceChange: bigint = isDepositOrRewardWithdrawal
405
+ ? amount
406
+ : bigIntMax(amount, -fromSPInteger(updatedAccountSnapshot.depositVal));
407
+ const newAccountSnapshot: StabilityPoolSnapshot = {
408
+ ...updatedAccountSnapshot,
409
+ depositVal: spAdd(
410
+ updatedAccountSnapshot.depositVal,
411
+ mkSPInteger(balanceChange),
412
+ ),
413
+ };
414
+
415
+ const _newPoolDepositExcludingFee = spAdd(
416
+ stabilityPoolDatum.snapshot.depositVal,
417
+ mkSPInteger(balanceChange),
418
+ );
419
+ const newPoolDepositExcludingFee =
420
+ _newPoolDepositExcludingFee.value > 0n
421
+ ? _newPoolDepositExcludingFee
422
+ : mkSPInteger(0n);
423
+
424
+ const withdrawalFee =
425
+ isDepositOrRewardWithdrawal || newPoolDepositExcludingFee.value === 0n
426
+ ? 0n
427
+ : calculateFeeFromPercentage(
428
+ iassetDatum.stabilityPoolWithdrawalFeePercentage,
429
+ -balanceChange,
430
+ );
431
+ const newPoolDeposit = spAdd(
432
+ newPoolDepositExcludingFee,
433
+ mkSPInteger(withdrawalFee),
434
+ );
435
+ const newPoolProduct =
436
+ withdrawalFee === 0n
437
+ ? stabilityPoolDatum.snapshot.productVal
438
+ : spMul(
439
+ stabilityPoolDatum.snapshot.productVal,
440
+ spAdd(
441
+ mkSPInteger(1n),
442
+ spDiv(mkSPInteger(withdrawalFee), newPoolDepositExcludingFee),
443
+ ),
444
+ );
445
+ const newPoolSum = spAdd(
446
+ stabilityPoolDatum.snapshot.sumVal,
447
+ spDiv(
448
+ spMul(
449
+ mkSPInteger(
450
+ BigInt(params.stabilityPoolParams.accountAdjustmentFeeLovelaces),
451
+ ),
452
+ newPoolProduct,
453
+ ),
454
+ newPoolDeposit,
455
+ ),
456
+ );
457
+ const newPoolSnapshot: StabilityPoolSnapshot = {
458
+ ...stabilityPoolDatum.snapshot,
459
+ depositVal: newPoolDeposit,
460
+ sumVal: newPoolSum,
461
+ productVal: newPoolProduct,
462
+ };
463
+ const newEpochToScaleToSum: EpochToScaleToSum = setSumInEpochToScaleToSum(
464
+ stabilityPoolDatum.epochToScaleToSum,
465
+ stabilityPoolDatum.snapshot.epoch,
466
+ stabilityPoolDatum.snapshot.scale,
467
+ newPoolSum,
468
+ );
469
+
470
+ await CollectorContract.feeTx(rewardLovelacesFee, lucid, params, tx);
471
+
472
+ tx.readFrom([govUtxo, iAssetUtxo, ...refInputs]);
473
+ tx.pay.ToContract(
474
+ stabilityPoolUtxo.address,
475
+ {
476
+ kind: 'inline',
477
+ value: serialiseStabilityPoolDatum({
478
+ StabilityPool: {
479
+ content: {
480
+ ...stabilityPoolDatum,
481
+ snapshot: newPoolSnapshot,
482
+ epochToScaleToSum: newEpochToScaleToSum,
483
+ },
484
+ },
485
+ }),
486
+ },
487
+ {
488
+ lovelace:
489
+ stabilityPoolUtxo.assets.lovelace +
490
+ BigInt(params.stabilityPoolParams.accountAdjustmentFeeLovelaces) -
491
+ reward,
492
+ [params.stabilityPoolParams.stabilityPoolToken[0].unCurrencySymbol +
493
+ fromText(
494
+ params.stabilityPoolParams.stabilityPoolToken[1].unTokenName,
495
+ )]: 1n,
496
+ [params.stabilityPoolParams.assetSymbol.unCurrencySymbol +
497
+ fromText(asset)]:
498
+ stabilityPoolUtxo.assets[
499
+ params.stabilityPoolParams.assetSymbol.unCurrencySymbol +
500
+ fromText(asset)
501
+ ] +
502
+ balanceChange +
503
+ withdrawalFee,
504
+ },
505
+ );
506
+
507
+ tx.pay.ToContract(
508
+ stabilityPoolUtxo.address,
509
+ {
510
+ kind: 'inline',
511
+ value: serialiseStabilityPoolDatum({
512
+ Account: {
513
+ content: {
514
+ ...accountDatum,
515
+ snapshot: newAccountSnapshot,
516
+ request: null,
517
+ },
518
+ },
519
+ }),
520
+ },
521
+ {
522
+ lovelace:
523
+ accountUtxo.assets.lovelace -
524
+ BigInt(params.stabilityPoolParams.accountAdjustmentFeeLovelaces) -
525
+ 2_000_000n,
526
+ [params.stabilityPoolParams.accountToken[0].unCurrencySymbol +
527
+ fromText(params.stabilityPoolParams.accountToken[1].unTokenName)]: 1n,
528
+ },
529
+ );
530
+
531
+ if (myAddress !== outputAddress) {
532
+ tx.pay.ToAddressWithData(
533
+ outputAddress,
534
+ {
535
+ kind: 'inline',
536
+ value: Data.to(
537
+ {
538
+ IndigoStabilityPoolAccountAdjustment: {
539
+ spent_account: {
540
+ txHash: { hash: accountUtxo.txHash },
541
+ outputIndex: BigInt(accountUtxo.outputIndex),
542
+ },
543
+ },
544
+ },
545
+ ActionReturnDatum,
546
+ ),
547
+ },
548
+ {
549
+ lovelace: reward - rewardLovelacesFee + 2_000_000n,
550
+ ...(amount < 0n
551
+ ? {
552
+ [params.stabilityPoolParams.assetSymbol.unCurrencySymbol +
553
+ fromText(asset)]: -(amount - withdrawalFee),
554
+ }
555
+ : {}),
556
+ },
557
+ );
558
+ } else {
559
+ // TODO: User is self-handling the process request, so we will need to handle the change datum
560
+ }
561
+ } else if ('Close' in accountDatum.request) {
562
+ const outputAddress = addressToBech32(
563
+ lucid,
564
+ accountDatum.request.Close.outputAddress,
565
+ );
566
+ const myAddress = await lucid.wallet().address();
567
+
568
+ const [updatedAccountSnapshot, reward, refInputs] = adjustmentHelper(
569
+ stabilityPoolUtxo,
570
+ newSnapshotUtxo,
571
+ stabilityPoolDatum.snapshot,
572
+ stabilityPoolDatum.epochToScaleToSum,
573
+ accountDatum.snapshot,
574
+ );
575
+
576
+ const govDatum: GovDatum = parseGovDatum(govUtxo.datum);
577
+ const iassetDatum: IAssetContent = parseIAssetDatum(iAssetUtxo.datum);
578
+ const rewardLovelacesFee = calculateFeeFromPercentage(
579
+ govDatum.protocolParams.collateralFeePercentage,
580
+ reward,
581
+ );
582
+
583
+ const fund = updatedAccountSnapshot.depositVal;
584
+ const newPoolDepositExcludingFee = spSub(
585
+ stabilityPoolDatum.snapshot.depositVal,
586
+ fund,
587
+ );
588
+ const withdrawnAmt = fund.value < 0n ? mkSPInteger(0n) : fund;
589
+ const withdrawalFeeAmount =
590
+ newPoolDepositExcludingFee.value === 0n
591
+ ? 0n
592
+ : calculateFeeFromPercentage(
593
+ iassetDatum.stabilityPoolWithdrawalFeePercentage,
594
+ withdrawnAmt.value,
595
+ );
596
+
597
+ const [newPoolDeposit, newPoolProduct] = updatePoolSnapshotWithdrawalFee(
598
+ mkSPInteger(withdrawalFeeAmount),
599
+ newPoolDepositExcludingFee,
600
+ stabilityPoolDatum.snapshot,
601
+ );
602
+ const newPoolSnapshot: StabilityPoolSnapshot = {
603
+ ...stabilityPoolDatum.snapshot,
604
+ depositVal: newPoolDeposit,
605
+ productVal: newPoolProduct,
606
+ };
607
+
608
+ const accountTokenRef = await scriptRef(
609
+ params.scriptReferences.authTokenPolicies.accountTokenRef,
610
+ lucid,
611
+ );
612
+
613
+ await CollectorContract.feeTx(rewardLovelacesFee, lucid, params, tx);
614
+
615
+ tx.readFrom([govUtxo, iAssetUtxo, accountTokenRef, ...refInputs]);
616
+
617
+ tx.mintAssets(
618
+ {
619
+ [params.stabilityPoolParams.accountToken[0].unCurrencySymbol +
620
+ fromText(params.stabilityPoolParams.accountToken[1].unTokenName)]:
621
+ -1n,
622
+ },
623
+ Data.to(new Constr(0, [])),
624
+ );
625
+
626
+ const assetOutputAmountForSP =
627
+ stabilityPoolUtxo.assets[
628
+ params.stabilityPoolParams.assetSymbol.unCurrencySymbol +
629
+ fromText(asset)
630
+ ] -
631
+ fromSPInteger(withdrawnAmt) -
632
+ withdrawalFeeAmount;
633
+
634
+ tx.pay.ToContract(
635
+ stabilityPoolUtxo.address,
636
+ {
637
+ kind: 'inline',
638
+ value: serialiseStabilityPoolDatum({
639
+ StabilityPool: {
640
+ content: {
641
+ ...stabilityPoolDatum,
642
+ snapshot: newPoolSnapshot,
643
+ },
644
+ },
645
+ }),
646
+ },
647
+ {
648
+ lovelace: stabilityPoolUtxo.assets.lovelace - reward,
649
+ [params.stabilityPoolParams.stabilityPoolToken[0].unCurrencySymbol +
650
+ fromText(
651
+ params.stabilityPoolParams.stabilityPoolToken[1].unTokenName,
652
+ )]: 1n,
653
+ ...(assetOutputAmountForSP > 0n
654
+ ? {
655
+ [params.stabilityPoolParams.assetSymbol.unCurrencySymbol +
656
+ fromText(asset)]: assetOutputAmountForSP,
657
+ }
658
+ : {}),
659
+ },
660
+ );
661
+
662
+ if (myAddress !== outputAddress) {
663
+ tx.pay.ToAddressWithData(
664
+ outputAddress,
665
+ {
666
+ kind: 'inline',
667
+ value: Data.to(
668
+ {
669
+ IndigoStabilityPoolAccountClosure: {
670
+ closed_account: {
671
+ txHash: { hash: accountUtxo.txHash },
672
+ outputIndex: BigInt(accountUtxo.outputIndex),
673
+ },
674
+ },
675
+ },
676
+ ActionReturnDatum,
677
+ ),
678
+ },
679
+ {
680
+ lovelace: accountUtxo.assets.lovelace + reward - rewardLovelacesFee,
681
+ [params.stabilityPoolParams.assetSymbol.unCurrencySymbol +
682
+ fromText(asset)]: fromSPInteger(withdrawnAmt) - withdrawalFeeAmount,
683
+ },
684
+ );
685
+ }
686
+ }
687
+
688
+ return tx;
689
+ }
690
+ }