@indigo-labs/indigo-sdk 0.2.42 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (202) hide show
  1. package/.github/workflows/ci.yml +4 -2
  2. package/README.md +88 -15
  3. package/dist/index.d.mts +3012 -2194
  4. package/dist/index.d.ts +3012 -2194
  5. package/dist/index.js +9849 -6198
  6. package/dist/index.mjs +8733 -4933
  7. package/package.json +14 -3
  8. package/src/contracts/cdp/helpers.ts +68 -72
  9. package/src/contracts/cdp/scripts.ts +50 -13
  10. package/src/contracts/cdp/transactions.ts +841 -546
  11. package/src/contracts/cdp/types-new.ts +256 -0
  12. package/src/contracts/cdp/types.ts +26 -144
  13. package/src/contracts/cdp-creator/scripts.ts +15 -9
  14. package/src/contracts/cdp-creator/types-new.ts +50 -0
  15. package/src/contracts/cdp-creator/types.ts +5 -31
  16. package/src/contracts/collector/scripts.ts +1 -1
  17. package/src/contracts/collector/transactions.ts +23 -13
  18. package/src/contracts/collector/types-new.ts +17 -0
  19. package/src/contracts/execute/scripts.ts +19 -10
  20. package/src/contracts/execute/types-new.ts +44 -0
  21. package/src/contracts/execute/types.ts +5 -38
  22. package/src/contracts/gov/helpers.ts +187 -51
  23. package/src/contracts/gov/scripts.ts +17 -10
  24. package/src/contracts/gov/transactions.ts +599 -271
  25. package/src/contracts/gov/types-new.ts +253 -100
  26. package/src/contracts/gov/types.ts +4 -71
  27. package/src/contracts/iasset/helpers.ts +172 -0
  28. package/src/contracts/iasset/scripts.ts +38 -0
  29. package/src/contracts/iasset/types.ts +154 -0
  30. package/src/contracts/initialize/actions.ts +768 -0
  31. package/src/contracts/initialize/helpers.ts +611 -36
  32. package/src/contracts/initialize/types.ts +102 -28
  33. package/src/contracts/interest-collection/helpers.ts +19 -0
  34. package/src/contracts/interest-collection/scripts.ts +44 -0
  35. package/src/contracts/interest-collection/transactions.ts +436 -0
  36. package/src/contracts/interest-collection/types-new.ts +50 -0
  37. package/src/contracts/interest-collection/types.ts +26 -0
  38. package/src/contracts/interest-oracle/helpers.ts +2 -30
  39. package/src/contracts/interest-oracle/scripts.ts +1 -1
  40. package/src/contracts/interest-oracle/transactions.ts +21 -16
  41. package/src/contracts/interest-oracle/types-new.ts +32 -0
  42. package/src/contracts/interest-oracle/types.ts +1 -40
  43. package/src/contracts/one-shot/transactions.ts +1 -2
  44. package/src/contracts/poll/helpers.ts +5 -23
  45. package/src/contracts/poll/scripts.ts +12 -13
  46. package/src/contracts/poll/types-poll-manager.ts +1 -19
  47. package/src/contracts/poll/types-poll-new.ts +170 -0
  48. package/src/contracts/poll/types-poll-shard.ts +2 -24
  49. package/src/contracts/price-oracle/helpers.ts +1 -4
  50. package/src/contracts/price-oracle/scripts.ts +3 -8
  51. package/src/contracts/price-oracle/transactions.ts +32 -25
  52. package/src/contracts/price-oracle/types-new.ts +50 -0
  53. package/src/contracts/price-oracle/types.ts +2 -36
  54. package/src/contracts/pyth-feed/helpers.ts +58 -0
  55. package/src/contracts/pyth-feed/scripts.ts +15 -0
  56. package/src/contracts/pyth-feed/types.ts +181 -0
  57. package/src/contracts/rob/helpers.ts +405 -0
  58. package/src/contracts/rob/scripts.ts +35 -0
  59. package/src/contracts/rob/transactions.ts +410 -0
  60. package/src/contracts/rob/types-new.ts +128 -0
  61. package/src/contracts/rob/types.ts +16 -0
  62. package/src/contracts/rob-leverage/helpers.ts +424 -0
  63. package/src/contracts/{leverage → rob-leverage}/transactions.ts +68 -48
  64. package/src/contracts/stability-pool/helpers.ts +714 -230
  65. package/src/contracts/stability-pool/scripts.ts +20 -15
  66. package/src/contracts/stability-pool/transactions.ts +628 -496
  67. package/src/contracts/stability-pool/types-new.ts +247 -100
  68. package/src/contracts/stability-pool/types.ts +5 -22
  69. package/src/contracts/stableswap/helpers.ts +22 -0
  70. package/src/contracts/stableswap/scripts.ts +37 -0
  71. package/src/contracts/stableswap/transactions.ts +647 -0
  72. package/src/contracts/stableswap/types-new.ts +131 -0
  73. package/src/contracts/stableswap/types.ts +17 -0
  74. package/src/contracts/staking/helpers.ts +49 -34
  75. package/src/contracts/staking/scripts.ts +1 -1
  76. package/src/contracts/staking/transactions.ts +85 -130
  77. package/src/contracts/staking/types-new.ts +60 -28
  78. package/src/contracts/staking/types.ts +1 -28
  79. package/src/contracts/treasury/helpers.ts +21 -0
  80. package/src/contracts/treasury/scripts.ts +16 -26
  81. package/src/contracts/treasury/transactions.ts +256 -27
  82. package/src/contracts/treasury/types-new.ts +69 -0
  83. package/src/contracts/treasury/types.ts +2 -43
  84. package/src/contracts/version-registry/scripts.ts +2 -2
  85. package/src/contracts/version-registry/types-new.ts +6 -7
  86. package/src/index.ts +37 -20
  87. package/src/scripts/auth-token-policy.ts +3 -2
  88. package/src/scripts/iasset-policy.ts +3 -2
  89. package/src/types/evolution-schema-options.ts +3 -3
  90. package/src/types/generic.ts +17 -89
  91. package/src/types/multisig.ts +48 -0
  92. package/src/types/on-chain-decimal.ts +14 -7
  93. package/src/types/rational.ts +61 -0
  94. package/src/types/system-params.ts +237 -41
  95. package/src/utils/array-utils.ts +70 -1
  96. package/src/utils/bigint-utils.ts +12 -0
  97. package/src/utils/indigo-helpers.ts +8 -10
  98. package/src/utils/lucid-utils.ts +47 -40
  99. package/src/utils/oracle-helpers.ts +62 -0
  100. package/src/utils/pyth/decode.ts +223 -0
  101. package/src/utils/pyth/encode.ts +262 -0
  102. package/src/utils/pyth/index.ts +14 -0
  103. package/src/utils/pyth/types.ts +87 -0
  104. package/src/validators/always-succeed-validator.ts +6 -0
  105. package/src/validators/cdp-creator-validator.ts +2 -2
  106. package/src/validators/cdp-redeem-validator.ts +7 -0
  107. package/src/validators/cdp-validator.ts +2 -2
  108. package/src/validators/collector-validator.ts +2 -2
  109. package/src/validators/execute-validator.ts +2 -2
  110. package/src/validators/governance-validator.ts +2 -2
  111. package/src/validators/iasset-validator.ts +7 -0
  112. package/src/validators/interest-collection-validator.ts +7 -0
  113. package/src/validators/interest-oracle-validator.ts +2 -2
  114. package/src/validators/poll-manager-validator.ts +2 -2
  115. package/src/validators/poll-shard-validator.ts +2 -2
  116. package/src/validators/price-oracle-validator.ts +7 -0
  117. package/src/validators/pyth-feed-validator.ts +7 -0
  118. package/src/validators/rob-validator.ts +7 -0
  119. package/src/validators/stability-pool-validator.ts +2 -2
  120. package/src/validators/stableswap-validator.ts +7 -0
  121. package/src/validators/staking-validator.ts +2 -2
  122. package/src/validators/treasury-validator.ts +2 -2
  123. package/src/validators/version-record-policy.ts +2 -2
  124. package/src/validators/version-registry-validator.ts +2 -2
  125. package/tests/always-succeed/script.ts +7 -0
  126. package/tests/bigint-utils.test.ts +41 -0
  127. package/tests/cdp/actions.ts +610 -0
  128. package/tests/cdp/cdp-helpers.ts +55 -0
  129. package/tests/cdp/cdp-queries.ts +440 -0
  130. package/tests/cdp/cdp.test.ts +6087 -0
  131. package/tests/cdp/transactions-mutated.ts +1729 -0
  132. package/tests/data/system-params.json +177 -34
  133. package/tests/datums.test.ts +209 -210
  134. package/tests/endpoints/initialize.ts +68 -0
  135. package/tests/endpoints/interest-collector.ts +37 -0
  136. package/tests/endpoints/treasury.ts +70 -0
  137. package/tests/gov/actions.ts +406 -0
  138. package/tests/gov/gov.test.ts +4450 -0
  139. package/tests/{queries → gov}/governance-queries.ts +6 -3
  140. package/tests/hash-checks.test.ts +38 -11
  141. package/tests/indigo-test-helpers.ts +100 -0
  142. package/tests/initialize.test.ts +61 -9
  143. package/tests/interest-collection/interest-collection.test.ts +892 -0
  144. package/tests/interest-collection/interest-collector-queries.ts +49 -0
  145. package/tests/interest-collection/transactions-mutated.ts +260 -0
  146. package/tests/interest-oracle.test.ts +43 -35
  147. package/tests/mock/assets-mock.ts +234 -23
  148. package/tests/mock/protocol-params-mock.ts +21 -0
  149. package/tests/price-oracle/actions.ts +163 -0
  150. package/tests/price-oracle/price-oracle-queries.ts +12 -0
  151. package/tests/price-oracle/price-oracle.test.ts +240 -0
  152. package/tests/price-oracle/transactions-mutated.ts +62 -0
  153. package/tests/pyth/endpoints.ts +96 -0
  154. package/tests/pyth/helpers.ts +37 -0
  155. package/tests/pyth/pyth-encoding.test.ts +376 -0
  156. package/tests/pyth/pyth-indigo.test.ts +509 -0
  157. package/tests/pyth/pyth.test.ts +300 -0
  158. package/tests/queries/execute-queries.ts +6 -5
  159. package/tests/queries/iasset-queries.ts +175 -5
  160. package/tests/queries/interest-oracle-queries.ts +4 -2
  161. package/tests/queries/poll-queries.ts +8 -9
  162. package/tests/queries/stability-pool-queries.ts +95 -48
  163. package/tests/queries/staking-queries.ts +4 -2
  164. package/tests/queries/treasury-queries.ts +80 -5
  165. package/tests/rob/actions.ts +58 -0
  166. package/tests/{lrp-leverage.test.ts → rob/rob-leverage.test.ts} +393 -296
  167. package/tests/rob/rob-queries.ts +95 -0
  168. package/tests/rob/rob.test.ts +3762 -0
  169. package/tests/rob/transactions-mutated.ts +853 -0
  170. package/tests/script-size.test.ts +240 -0
  171. package/tests/setup.ts +135 -0
  172. package/tests/stability-pool/actions.ts +220 -0
  173. package/tests/stability-pool.test.ts +6121 -667
  174. package/tests/stableswap/stableswap-actions.ts +84 -0
  175. package/tests/stableswap/stableswap-queries.ts +89 -0
  176. package/tests/stableswap/stableswap.test.ts +3891 -0
  177. package/tests/stableswap/transactions-mutated.ts +348 -0
  178. package/tests/staking.test.ts +82 -99
  179. package/tests/test-helpers.ts +58 -11
  180. package/tests/treasury.test.ts +242 -0
  181. package/tests/utils/asserts.ts +74 -0
  182. package/tests/utils/benchmark-utils.ts +81 -0
  183. package/tests/utils/index.ts +122 -4
  184. package/tsconfig.json +9 -1
  185. package/vitest.config.ts +3 -1
  186. package/src/contracts/collector/types.ts +0 -16
  187. package/src/contracts/initialize/transactions.ts +0 -891
  188. package/src/contracts/leverage/helpers.ts +0 -424
  189. package/src/contracts/lrp/helpers.ts +0 -294
  190. package/src/contracts/lrp/scripts.ts +0 -27
  191. package/src/contracts/lrp/transactions.ts +0 -250
  192. package/src/contracts/lrp/types.ts +0 -131
  193. package/src/contracts/poll/types-poll.ts +0 -88
  194. package/src/contracts/vesting/helpers.ts +0 -218
  195. package/src/utils/value-helpers.ts +0 -37
  196. package/src/validators/lrp-validator.ts +0 -7
  197. package/tests/cdp.test.ts +0 -1528
  198. package/tests/gov.test.ts +0 -2011
  199. package/tests/lrp.test.ts +0 -673
  200. package/tests/queries/cdp-queries.ts +0 -220
  201. package/tests/queries/lrp-queries.ts +0 -76
  202. package/tests/queries/price-oracle-queries.ts +0 -10
@@ -0,0 +1,853 @@
1
+ import {
2
+ addAssets,
3
+ Data,
4
+ fromHex,
5
+ getInputIndices,
6
+ LucidEvolution,
7
+ OutRef,
8
+ slotToUnixTime,
9
+ toHex,
10
+ TxBuilder,
11
+ } from '@lucid-evolution/lucid';
12
+ import {
13
+ addrDetails,
14
+ buildRedemptionsTx,
15
+ collectInterestTx,
16
+ createScriptAddress,
17
+ fromSystemParamsAsset,
18
+ fromSystemParamsScriptRef,
19
+ getInlineDatumOrThrow,
20
+ matchSingle,
21
+ SystemParams,
22
+ treasuryFeeTx,
23
+ } from '../../src';
24
+ import {
25
+ parseCollateralAssetDatumOrThrow,
26
+ parseIAssetDatumOrThrow,
27
+ } from '../../src/contracts/iasset/types';
28
+ import { match, P } from 'ts-pattern';
29
+ import { parsePriceOracleDatum } from '../../src/contracts/price-oracle/types-new';
30
+ import { unzip, zip } from 'fp-ts/lib/Array';
31
+ import {
32
+ parseCdpDatumOrThrow,
33
+ serialiseCdpDatum,
34
+ serialiseCdpRedeemer,
35
+ } from '../../src/contracts/cdp/types-new';
36
+ import { parseInterestOracleDatum } from '../../src/contracts/interest-oracle/types-new';
37
+ import {
38
+ calculateAccruedInterest,
39
+ calculateUnitaryInterestSinceOracleLastUpdated,
40
+ } from '../../src/contracts/interest-oracle/helpers';
41
+ import { mkAssetsOf } from '@3rd-eye-labs/cardano-offchain-common';
42
+ import { oracleExpirationAwareValidity } from '../../src/contracts/price-oracle/helpers';
43
+ import { calculateFeeFromRatio } from '../../src/utils/indigo-helpers';
44
+ import {
45
+ serialiseCDPCreatorDatum,
46
+ serialiseCDPCreatorRedeemer,
47
+ } from '../../src/contracts/cdp-creator/types-new';
48
+ import { retrieveAdjustedPrice } from '../../src/utils/oracle-helpers';
49
+
50
+ // Unlike the real redeemRob function, this one allows building a transaction to redeem
51
+ // using a delisted iAsset. Therefore, no price oracle is required.
52
+ export async function testRedeemRob(
53
+ redemptionRobsData: [OutRef, bigint][],
54
+ priceOracleOutRef: OutRef | undefined,
55
+ iassetOutRef: OutRef,
56
+ collateralAssetOutRef: OutRef,
57
+ lucid: LucidEvolution,
58
+ currentSlot: number,
59
+ sysParams: SystemParams,
60
+ pythMessage?: string,
61
+ ): Promise<TxBuilder> {
62
+ const network = lucid.config().network!;
63
+
64
+ const robScriptRefUtxo = matchSingle(
65
+ await lucid.utxosByOutRef([
66
+ fromSystemParamsScriptRef(sysParams.scriptReferences.robValidatorRef),
67
+ ]),
68
+ (_) => new Error('Expected a single ROB Ref Script UTXO'),
69
+ );
70
+
71
+ const iassetUtxo = matchSingle(
72
+ await lucid.utxosByOutRef([iassetOutRef]),
73
+ (_) => new Error('Expected a single IAsset UTXO'),
74
+ );
75
+
76
+ const iassetDatum = parseIAssetDatumOrThrow(
77
+ getInlineDatumOrThrow(iassetUtxo),
78
+ );
79
+
80
+ const collateralAssetUtxo = matchSingle(
81
+ await lucid.utxosByOutRef([collateralAssetOutRef]),
82
+ (_) => new Error('Expected a single collateral asset UTXO'),
83
+ );
84
+
85
+ const collateralAssetDatum = parseCollateralAssetDatumOrThrow(
86
+ getInlineDatumOrThrow(collateralAssetUtxo),
87
+ );
88
+
89
+ const [adjustedPrice, priceOracleUtxo] = await retrieveAdjustedPrice(
90
+ iassetDatum.assetName,
91
+ collateralAssetDatum.collateralAsset,
92
+ collateralAssetDatum.priceInfo,
93
+ collateralAssetDatum.extraDecimals,
94
+ priceOracleOutRef,
95
+ pythMessage,
96
+ sysParams.pythConfig,
97
+ lucid,
98
+ );
99
+
100
+ const [robsToRedeemOutRefs, robRedemptionIAssetAmt] =
101
+ unzip(redemptionRobsData);
102
+
103
+ const redemptionRobs = await lucid
104
+ .utxosByOutRef(robsToRedeemOutRefs)
105
+ .then((val) => zip(val, robRedemptionIAssetAmt));
106
+
107
+ const allRefInputs = [
108
+ robScriptRefUtxo,
109
+ iassetUtxo,
110
+ collateralAssetUtxo,
111
+ ...(priceOracleUtxo == null ? [] : [priceOracleUtxo]),
112
+ ];
113
+
114
+ const refInputIdxs = getInputIndices(allRefInputs, allRefInputs);
115
+
116
+ const tx = buildRedemptionsTx(
117
+ redemptionRobs,
118
+ iassetDatum.assetName,
119
+ collateralAssetDatum.collateralAsset,
120
+ adjustedPrice,
121
+ iassetDatum.redemptionReimbursementRatio,
122
+ sysParams,
123
+ lucid.newTx(),
124
+ 0n,
125
+ refInputIdxs[2],
126
+ refInputIdxs[1],
127
+ priceOracleUtxo !== undefined ? refInputIdxs[3] : null,
128
+ );
129
+
130
+ const transaction = lucid
131
+ .newTx()
132
+ .validTo(slotToUnixTime(network, currentSlot))
133
+ .readFrom(allRefInputs)
134
+ .compose(tx);
135
+
136
+ if (priceOracleUtxo != null) {
137
+ transaction.readFrom([priceOracleUtxo]);
138
+ }
139
+
140
+ return transaction;
141
+ }
142
+
143
+ export async function redeemWithCdpCreate(
144
+ redemptionRobsData: [OutRef, bigint][],
145
+ collateralAmount: bigint,
146
+ mintedAmount: bigint,
147
+ sysParams: SystemParams,
148
+ cdpCreatorOref: OutRef,
149
+ iassetOref: OutRef,
150
+ collateralAssetOref: OutRef,
151
+ priceOracleOref: OutRef,
152
+ interestOracleOref: OutRef,
153
+ treasuryOref: OutRef,
154
+ lucid: LucidEvolution,
155
+ currentSlot: number,
156
+ ): Promise<TxBuilder> {
157
+ const network = lucid.config().network!;
158
+ const currentTime = BigInt(slotToUnixTime(network, currentSlot));
159
+
160
+ const [pkh, skh] = await addrDetails(lucid);
161
+
162
+ const treasuryRefScriptUtxo = matchSingle(
163
+ await lucid.utxosByOutRef([
164
+ fromSystemParamsScriptRef(
165
+ sysParams.scriptReferences.treasuryValidatorRef,
166
+ ),
167
+ ]),
168
+ (_) => new Error('Expected a single treasury Ref Script UTXO'),
169
+ );
170
+
171
+ const robScriptRefUtxo = matchSingle(
172
+ await lucid.utxosByOutRef([
173
+ fromSystemParamsScriptRef(sysParams.scriptReferences.robValidatorRef),
174
+ ]),
175
+ (_) => new Error('Expected a single ROB Ref Script UTXO'),
176
+ );
177
+
178
+ const cdpCreatorRefScriptUtxo = matchSingle(
179
+ await lucid.utxosByOutRef([
180
+ fromSystemParamsScriptRef(
181
+ sysParams.scriptReferences.cdpCreatorValidatorRef,
182
+ ),
183
+ ]),
184
+ (_) => new Error('Expected a single cdp creator Ref Script UTXO'),
185
+ );
186
+ const cdpAuthTokenPolicyRefScriptUtxo = matchSingle(
187
+ await lucid.utxosByOutRef([
188
+ fromSystemParamsScriptRef(
189
+ sysParams.scriptReferences.authTokenPolicies.cdpAuthTokenRef,
190
+ ),
191
+ ]),
192
+ (_) => new Error('Expected a single cdp auth token policy Ref Script UTXO'),
193
+ );
194
+ const iAssetTokenPolicyRefScriptUtxo = matchSingle(
195
+ await lucid.utxosByOutRef([
196
+ fromSystemParamsScriptRef(
197
+ sysParams.scriptReferences.iAssetTokenPolicyRef,
198
+ ),
199
+ ]),
200
+ (_) => new Error('Expected a single iasset token policy Ref Script UTXO'),
201
+ );
202
+
203
+ const iassetUtxo = matchSingle(
204
+ await lucid.utxosByOutRef([iassetOref]),
205
+ (_) => new Error('Expected a single iasset UTXO'),
206
+ );
207
+ const iassetDatum = parseIAssetDatumOrThrow(
208
+ getInlineDatumOrThrow(iassetUtxo),
209
+ );
210
+
211
+ const collateralAssetUtxo = matchSingle(
212
+ await lucid.utxosByOutRef([collateralAssetOref]),
213
+ (_) => new Error('Expected a single collateral asset UTXO'),
214
+ );
215
+ const collateralAssetDatum = parseCollateralAssetDatumOrThrow(
216
+ getInlineDatumOrThrow(collateralAssetUtxo),
217
+ );
218
+
219
+ const priceOracleUtxo = matchSingle(
220
+ await lucid.utxosByOutRef([priceOracleOref]),
221
+ (_) => new Error('Expected a single price oracle UTXO'),
222
+ );
223
+ const priceOracleDatum = parsePriceOracleDatum(
224
+ getInlineDatumOrThrow(priceOracleUtxo),
225
+ );
226
+
227
+ const interestOracleUtxo = matchSingle(
228
+ await lucid.utxosByOutRef([interestOracleOref]),
229
+ (_) => new Error('Expected a single interest oracle UTXO'),
230
+ );
231
+ const interestOracleDatum = parseInterestOracleDatum(
232
+ getInlineDatumOrThrow(interestOracleUtxo),
233
+ );
234
+
235
+ const cdpCreatorUtxo = matchSingle(
236
+ await lucid.utxosByOutRef([cdpCreatorOref]),
237
+ (_) => new Error('Expected a single CDP creator UTXO'),
238
+ );
239
+
240
+ match(collateralAssetDatum.priceInfo)
241
+ .with({ Delisted: P.any }, () => {
242
+ throw new Error("Can't open CDP of delisted asset");
243
+ })
244
+ .otherwise(() => {});
245
+
246
+ const cdpNftVal = mkAssetsOf(
247
+ fromSystemParamsAsset(sysParams.cdpParams.cdpAuthToken),
248
+ 1n,
249
+ );
250
+
251
+ const iassetClass = {
252
+ currencySymbol: fromHex(
253
+ sysParams.cdpParams.cdpAssetSymbol.unCurrencySymbol,
254
+ ),
255
+ tokenName: iassetDatum.assetName,
256
+ };
257
+
258
+ const debtMintingFee = calculateFeeFromRatio(
259
+ iassetDatum.debtMintingFeeRatio,
260
+ mintedAmount,
261
+ );
262
+
263
+ const iassetTokensVal = mkAssetsOf(iassetClass, mintedAmount);
264
+
265
+ const [robsToRedeemOutRefs, robRedemptionIAssetAmt] =
266
+ unzip(redemptionRobsData);
267
+
268
+ const redemptionRobs = await lucid
269
+ .utxosByOutRef(robsToRedeemOutRefs)
270
+ .then((val) => zip(val, robRedemptionIAssetAmt));
271
+
272
+ const allRefInputs = [
273
+ collateralAssetUtxo,
274
+ iassetUtxo,
275
+ priceOracleUtxo,
276
+ interestOracleUtxo,
277
+ // ref scripts
278
+ cdpCreatorRefScriptUtxo,
279
+ robScriptRefUtxo,
280
+ iAssetTokenPolicyRefScriptUtxo,
281
+ cdpAuthTokenPolicyRefScriptUtxo,
282
+ ...(debtMintingFee > 0n ? [treasuryRefScriptUtxo] : []),
283
+ ];
284
+
285
+ const refInputIdxs = getInputIndices(allRefInputs, allRefInputs);
286
+
287
+ const tx = buildRedemptionsTx(
288
+ redemptionRobs,
289
+ iassetDatum.assetName,
290
+ collateralAssetDatum.collateralAsset,
291
+ priceOracleDatum.price,
292
+ iassetDatum.redemptionReimbursementRatio,
293
+ sysParams,
294
+ lucid.newTx(),
295
+ 0n,
296
+ refInputIdxs[0],
297
+ refInputIdxs[1],
298
+ refInputIdxs[2],
299
+ );
300
+
301
+ const txValidity = oracleExpirationAwareValidity(
302
+ currentSlot,
303
+ Number(sysParams.cdpCreatorParams.biasTime),
304
+ Number(priceOracleDatum.expirationTime),
305
+ network,
306
+ );
307
+
308
+ tx.validFrom(txValidity.validFrom)
309
+ .validTo(txValidity.validTo)
310
+ // Ref scripts
311
+ .readFrom(allRefInputs)
312
+ .mintAssets(cdpNftVal, Data.void())
313
+ .mintAssets(iassetTokensVal, Data.void())
314
+ .pay.ToContract(
315
+ createScriptAddress(network, sysParams.validatorHashes.cdpHash, skh),
316
+ {
317
+ kind: 'inline',
318
+ value: serialiseCdpDatum({
319
+ cdpOwner: fromHex(pkh.hash),
320
+ iasset: iassetDatum.assetName,
321
+ collateralAsset: collateralAssetDatum.collateralAsset,
322
+ mintedAmt: mintedAmount,
323
+ cdpFees: {
324
+ ActiveCDPInterestTracking: {
325
+ lastSettled: currentTime,
326
+ unitaryInterestSnapshot:
327
+ calculateUnitaryInterestSinceOracleLastUpdated(
328
+ currentTime,
329
+ interestOracleDatum,
330
+ ) + interestOracleDatum.unitaryInterest,
331
+ },
332
+ },
333
+ }),
334
+ },
335
+ addAssets(
336
+ cdpNftVal,
337
+ mkAssetsOf(collateralAssetDatum.collateralAsset, collateralAmount),
338
+ ),
339
+ )
340
+ .pay.ToContract(
341
+ cdpCreatorUtxo.address,
342
+ {
343
+ kind: 'inline',
344
+ value: serialiseCDPCreatorDatum({
345
+ creatorInputOref: {
346
+ outputIndex: BigInt(cdpCreatorUtxo.outputIndex),
347
+ txHash: fromHex(cdpCreatorUtxo.txHash),
348
+ },
349
+ }),
350
+ },
351
+ cdpCreatorUtxo.assets,
352
+ );
353
+
354
+ if (debtMintingFee > 0) {
355
+ await treasuryFeeTx(
356
+ iassetClass,
357
+ debtMintingFee,
358
+ 0n,
359
+ lucid,
360
+ sysParams,
361
+ tx,
362
+ cdpCreatorUtxo,
363
+ treasuryOref,
364
+ );
365
+ }
366
+
367
+ tx.collectFrom([cdpCreatorUtxo], {
368
+ kind: 'self',
369
+ makeRedeemer: (inputIdx) => {
370
+ return serialiseCDPCreatorRedeemer({
371
+ CreateCDP: {
372
+ cdpOwner: fromHex(pkh.hash),
373
+ minted: mintedAmount,
374
+ collateralAmt: collateralAmount,
375
+ currentTime: currentTime,
376
+ creatorInputIdx: inputIdx,
377
+ creatorOutputIdx: BigInt(redemptionRobs.length) + 1n,
378
+ cdpOutputIdx: BigInt(redemptionRobs.length),
379
+ iassetRefInputIdx: refInputIdxs[1],
380
+ collateralAssetRefInputIdx: refInputIdxs[0],
381
+ interestOracleRefInputIdx: refInputIdxs[3],
382
+ priceOracleIdx: { OracleRefInputIdx: refInputIdxs[2] },
383
+ },
384
+ });
385
+ },
386
+ });
387
+
388
+ return tx;
389
+ }
390
+
391
+ export async function redeemWithCdpClose(
392
+ redemptionRobsData: [OutRef, bigint][],
393
+ cdpOref: OutRef,
394
+ iassetOref: OutRef,
395
+ collateralAssetOref: OutRef,
396
+ priceOracleOref: OutRef,
397
+ interestOracleOref: OutRef,
398
+ interestCollectorOref: OutRef,
399
+ sysParams: SystemParams,
400
+ lucid: LucidEvolution,
401
+ currentSlot: number,
402
+ ): Promise<TxBuilder> {
403
+ const network = lucid.config().network!;
404
+ const currentTime = BigInt(slotToUnixTime(network, currentSlot));
405
+
406
+ const robScriptRefUtxo = matchSingle(
407
+ await lucid.utxosByOutRef([
408
+ fromSystemParamsScriptRef(sysParams.scriptReferences.robValidatorRef),
409
+ ]),
410
+ (_) => new Error('Expected a single ROB Ref Script UTXO'),
411
+ );
412
+
413
+ const cdpRefScriptUtxo = matchSingle(
414
+ await lucid.utxosByOutRef([
415
+ fromSystemParamsScriptRef(sysParams.scriptReferences.cdpValidatorRef),
416
+ ]),
417
+ (_) => new Error('Expected a single cdp Ref Script UTXO'),
418
+ );
419
+
420
+ const interestCollectorRefScriptUtxo = matchSingle(
421
+ await lucid.utxosByOutRef([
422
+ fromSystemParamsScriptRef(
423
+ sysParams.scriptReferences.interestCollectionValidatorRef,
424
+ ),
425
+ ]),
426
+ (_) => new Error('Expected a single interest collector Ref Script UTXO'),
427
+ );
428
+
429
+ const cdpAuthTokenPolicyRefScriptUtxo = matchSingle(
430
+ await lucid.utxosByOutRef([
431
+ fromSystemParamsScriptRef(
432
+ sysParams.scriptReferences.authTokenPolicies.cdpAuthTokenRef,
433
+ ),
434
+ ]),
435
+ (_) => new Error('Expected a single cdp auth token policy Ref Script UTXO'),
436
+ );
437
+
438
+ const iAssetTokenPolicyRefScriptUtxo = matchSingle(
439
+ await lucid.utxosByOutRef([
440
+ fromSystemParamsScriptRef(
441
+ sysParams.scriptReferences.iAssetTokenPolicyRef,
442
+ ),
443
+ ]),
444
+ (_) => new Error('Expected a single iasset token policy Ref Script UTXO'),
445
+ );
446
+
447
+ const cdpUtxo = matchSingle(
448
+ await lucid.utxosByOutRef([cdpOref]),
449
+ (_) => new Error('Expected a single cdp UTXO'),
450
+ );
451
+ const cdpDatum = parseCdpDatumOrThrow(getInlineDatumOrThrow(cdpUtxo));
452
+
453
+ const collateralAssetUtxo = matchSingle(
454
+ await lucid.utxosByOutRef([collateralAssetOref]),
455
+ (_) => new Error('Expected a single collateral asset UTXO'),
456
+ );
457
+ const collateralDatum = parseCollateralAssetDatumOrThrow(
458
+ getInlineDatumOrThrow(collateralAssetUtxo),
459
+ );
460
+
461
+ const iassetUtxo = matchSingle(
462
+ await lucid.utxosByOutRef([iassetOref]),
463
+ (_) => new Error('Expected a single iasset UTXO'),
464
+ );
465
+
466
+ const iassetDatum = parseIAssetDatumOrThrow(
467
+ getInlineDatumOrThrow(iassetUtxo),
468
+ );
469
+
470
+ const priceOracleUtxo = matchSingle(
471
+ await lucid.utxosByOutRef([priceOracleOref]),
472
+ (_) => new Error('Expected a single price oracle UTXO'),
473
+ );
474
+ const priceOracleDatum = parsePriceOracleDatum(
475
+ getInlineDatumOrThrow(priceOracleUtxo),
476
+ );
477
+
478
+ const interestOracleUtxo = matchSingle(
479
+ await lucid.utxosByOutRef([interestOracleOref]),
480
+ (_) => new Error('Expected a single interest oracle UTXO'),
481
+ );
482
+ const interestOracleDatum = parseInterestOracleDatum(
483
+ getInlineDatumOrThrow(interestOracleUtxo),
484
+ );
485
+
486
+ const interestAmt = match(cdpDatum.cdpFees)
487
+ .with({ FrozenCDPAccumulatedFees: P.any }, () => {
488
+ throw new Error('CDP fees wrong');
489
+ })
490
+ .with({ ActiveCDPInterestTracking: P.select() }, (interest) => {
491
+ return calculateAccruedInterest(
492
+ currentTime,
493
+ interest.unitaryInterestSnapshot,
494
+ cdpDatum.mintedAmt,
495
+ interest.lastSettled,
496
+ interestOracleDatum,
497
+ );
498
+ })
499
+ .exhaustive();
500
+
501
+ const [robsToRedeemOutRefs, robRedemptionIAssetAmt] =
502
+ unzip(redemptionRobsData);
503
+
504
+ const redemptionRobs = await lucid
505
+ .utxosByOutRef(robsToRedeemOutRefs)
506
+ .then((val) => zip(val, robRedemptionIAssetAmt));
507
+
508
+ const allRefInputs = [
509
+ collateralAssetUtxo,
510
+ iassetUtxo,
511
+ priceOracleUtxo,
512
+ interestOracleUtxo,
513
+ // ref scripts
514
+ robScriptRefUtxo,
515
+ cdpRefScriptUtxo,
516
+ iAssetTokenPolicyRefScriptUtxo,
517
+ cdpAuthTokenPolicyRefScriptUtxo,
518
+ ];
519
+
520
+ const allAll = [
521
+ ...allRefInputs,
522
+ ...(interestAmt > 0n ? [interestCollectorRefScriptUtxo] : []),
523
+ ];
524
+ const refInputIdxs = getInputIndices(allRefInputs, allAll);
525
+
526
+ const tx = buildRedemptionsTx(
527
+ redemptionRobs,
528
+ iassetDatum.assetName,
529
+ collateralDatum.collateralAsset,
530
+ priceOracleDatum.price,
531
+ iassetDatum.redemptionReimbursementRatio,
532
+ sysParams,
533
+ lucid.newTx(),
534
+ 0n,
535
+ refInputIdxs[0],
536
+ refInputIdxs[1],
537
+ refInputIdxs[2],
538
+ );
539
+
540
+ const validateFrom = slotToUnixTime(network, currentSlot - 1);
541
+ const validateTo = Math.min(
542
+ Number(BigInt(validateFrom) + sysParams.cdpParams.biasTime / 2n),
543
+ Number(priceOracleDatum.expirationTime - 1n * 1000n),
544
+ );
545
+
546
+ tx.validFrom(validateFrom)
547
+ .validTo(validateTo)
548
+ .readFrom(allRefInputs)
549
+ .mintAssets(
550
+ mkAssetsOf(
551
+ {
552
+ currencySymbol: fromHex(
553
+ sysParams.cdpParams.cdpAssetSymbol.unCurrencySymbol,
554
+ ),
555
+ tokenName: collateralDatum.iasset,
556
+ },
557
+ -cdpDatum.mintedAmt,
558
+ ),
559
+ Data.void(),
560
+ )
561
+ .mintAssets(
562
+ mkAssetsOf(fromSystemParamsAsset(sysParams.cdpParams.cdpAuthToken), -1n),
563
+ Data.void(),
564
+ )
565
+ .collectFrom(
566
+ [cdpUtxo],
567
+ serialiseCdpRedeemer({ CloseCdp: { currentTime: currentTime } }),
568
+ )
569
+ // TODO: this is just a placeholder
570
+ .setMinFee(3_000_000n);
571
+
572
+ if (!cdpDatum.cdpOwner) {
573
+ throw new Error('Expected active CDP');
574
+ }
575
+
576
+ tx.addSignerKey(toHex(cdpDatum.cdpOwner));
577
+
578
+ if (interestAmt > 0n) {
579
+ await collectInterestTx(
580
+ mkAssetsOf(
581
+ {
582
+ currencySymbol: fromHex(
583
+ sysParams.cdpParams.cdpAssetSymbol.unCurrencySymbol,
584
+ ),
585
+ tokenName: collateralDatum.iasset,
586
+ },
587
+ interestAmt,
588
+ ),
589
+ lucid,
590
+ sysParams,
591
+ tx,
592
+ interestCollectorOref,
593
+ );
594
+ }
595
+
596
+ return tx;
597
+ }
598
+
599
+ export async function redeemWithCdpAdjust(
600
+ redemptionRobsData: [OutRef, bigint][],
601
+ /// cdp adjust params
602
+ collateralAdjustment: bigint,
603
+ debtAdjustment: bigint,
604
+ cdpOref: OutRef,
605
+ iassetOref: OutRef,
606
+ collateralAssetOref: OutRef,
607
+ priceOracleOref: OutRef,
608
+ interestOracleOref: OutRef,
609
+ treasuryOref: OutRef,
610
+ interestCollectorOref: OutRef,
611
+ currentSlot: number,
612
+ lucid: LucidEvolution,
613
+ sysParams: SystemParams,
614
+ ): Promise<TxBuilder> {
615
+ const network = lucid.config().network!;
616
+ const currentTime = BigInt(slotToUnixTime(network, currentSlot));
617
+
618
+ const robScriptRefUtxo = matchSingle(
619
+ await lucid.utxosByOutRef([
620
+ fromSystemParamsScriptRef(sysParams.scriptReferences.robValidatorRef),
621
+ ]),
622
+ (_) => new Error('Expected a single ROB Ref Script UTXO'),
623
+ );
624
+
625
+ const cdpRefScriptUtxo = matchSingle(
626
+ await lucid.utxosByOutRef([
627
+ fromSystemParamsScriptRef(sysParams.scriptReferences.cdpValidatorRef),
628
+ ]),
629
+ (_) => new Error('Expected a single cdp Ref Script UTXO'),
630
+ );
631
+
632
+ const iAssetTokenPolicyRefScriptUtxo = matchSingle(
633
+ await lucid.utxosByOutRef([
634
+ fromSystemParamsScriptRef(
635
+ sysParams.scriptReferences.iAssetTokenPolicyRef,
636
+ ),
637
+ ]),
638
+ (_) => new Error('Expected a single iasset token policy Ref Script UTXO'),
639
+ );
640
+
641
+ const interestCollectorRefScriptUtxo = matchSingle(
642
+ await lucid.utxosByOutRef([
643
+ fromSystemParamsScriptRef(
644
+ sysParams.scriptReferences.interestCollectionValidatorRef,
645
+ ),
646
+ ]),
647
+ (_) => new Error('Expected a single interest collector Ref Script UTXO'),
648
+ );
649
+
650
+ const treasuryRefScriptUtxo = matchSingle(
651
+ await lucid.utxosByOutRef([
652
+ fromSystemParamsScriptRef(
653
+ sysParams.scriptReferences.treasuryValidatorRef,
654
+ ),
655
+ ]),
656
+ (_) => new Error('Expected a single treasury Ref Script UTXO'),
657
+ );
658
+
659
+ const cdpUtxo = matchSingle(
660
+ await lucid.utxosByOutRef([cdpOref]),
661
+ (_) => new Error('Expected a single cdp UTXO'),
662
+ );
663
+ const cdpDatum = parseCdpDatumOrThrow(getInlineDatumOrThrow(cdpUtxo));
664
+
665
+ const iassetUtxo = matchSingle(
666
+ await lucid.utxosByOutRef([iassetOref]),
667
+ (_) => new Error('Expected a single iasset UTXO'),
668
+ );
669
+
670
+ const iassetDatum = parseIAssetDatumOrThrow(
671
+ getInlineDatumOrThrow(iassetUtxo),
672
+ );
673
+
674
+ const collateralAssetUtxo = matchSingle(
675
+ await lucid.utxosByOutRef([collateralAssetOref]),
676
+ (_) => new Error('Expected a single collateral asset UTXO'),
677
+ );
678
+ const collateralAssetDatum = parseCollateralAssetDatumOrThrow(
679
+ getInlineDatumOrThrow(collateralAssetUtxo),
680
+ );
681
+
682
+ const priceOracleUtxo = matchSingle(
683
+ await lucid.utxosByOutRef([priceOracleOref]),
684
+ (_) => new Error('Expected a single price oracle UTXO'),
685
+ );
686
+ const priceOracleDatum = parsePriceOracleDatum(
687
+ getInlineDatumOrThrow(priceOracleUtxo),
688
+ );
689
+
690
+ const interestOracleUtxo = matchSingle(
691
+ await lucid.utxosByOutRef([interestOracleOref]),
692
+ (_) => new Error('Expected a single interest oracle UTXO'),
693
+ );
694
+ const interestOracleDatum = parseInterestOracleDatum(
695
+ getInlineDatumOrThrow(interestOracleUtxo),
696
+ );
697
+
698
+ const interestAmt = match(cdpDatum.cdpFees)
699
+ .with({ FrozenCDPAccumulatedFees: P.any }, () => {
700
+ throw new Error('CDP fees wrong');
701
+ })
702
+ .with({ ActiveCDPInterestTracking: P.select() }, (interest) => {
703
+ return calculateAccruedInterest(
704
+ currentTime,
705
+ interest.unitaryInterestSnapshot,
706
+ cdpDatum.mintedAmt,
707
+ interest.lastSettled,
708
+ interestOracleDatum,
709
+ );
710
+ })
711
+ .exhaustive();
712
+
713
+ const mintedAmountChange = debtAdjustment + interestAmt;
714
+
715
+ let treasuryFee = 0n;
716
+
717
+ // when mint
718
+ if (debtAdjustment > 0n) {
719
+ treasuryFee += calculateFeeFromRatio(
720
+ iassetDatum.debtMintingFeeRatio,
721
+ debtAdjustment,
722
+ );
723
+ }
724
+
725
+ const [robsToRedeemOutRefs, robRedemptionIAssetAmt] =
726
+ unzip(redemptionRobsData);
727
+
728
+ const redemptionRobs = await lucid
729
+ .utxosByOutRef(robsToRedeemOutRefs)
730
+ .then((val) => zip(val, robRedemptionIAssetAmt));
731
+
732
+ const allRefInputs = [
733
+ collateralAssetUtxo,
734
+ iassetUtxo,
735
+ priceOracleUtxo,
736
+ interestOracleUtxo,
737
+ // ref scripts
738
+ robScriptRefUtxo,
739
+ cdpRefScriptUtxo,
740
+ iAssetTokenPolicyRefScriptUtxo,
741
+ ];
742
+
743
+ const allAll = [
744
+ ...allRefInputs,
745
+ ...(interestAmt > 0n ? [interestCollectorRefScriptUtxo] : []),
746
+ ...(treasuryFee > 0n ? [treasuryRefScriptUtxo] : []),
747
+ ];
748
+ const refInputIdxs = getInputIndices(allRefInputs, allAll);
749
+
750
+ const tx = buildRedemptionsTx(
751
+ redemptionRobs,
752
+ iassetDatum.assetName,
753
+ collateralAssetDatum.collateralAsset,
754
+ priceOracleDatum.price,
755
+ iassetDatum.redemptionReimbursementRatio,
756
+ sysParams,
757
+ lucid.newTx(),
758
+ 0n,
759
+ refInputIdxs[0],
760
+ refInputIdxs[1],
761
+ refInputIdxs[2],
762
+ );
763
+
764
+ const txValidity = oracleExpirationAwareValidity(
765
+ currentSlot,
766
+ Number(sysParams.cdpCreatorParams.biasTime),
767
+ Number(priceOracleDatum.expirationTime),
768
+ network,
769
+ );
770
+
771
+ tx.validFrom(txValidity.validFrom)
772
+ .validTo(txValidity.validTo)
773
+ .readFrom(allRefInputs)
774
+ .collectFrom(
775
+ [cdpUtxo],
776
+ serialiseCdpRedeemer({
777
+ AdjustCdp: {
778
+ currentTime: currentTime,
779
+ debtAdjustment: debtAdjustment,
780
+ collateralAdjustment,
781
+ priceOracleIdx: { OracleRefInputIdx: refInputIdxs[2] },
782
+ },
783
+ }),
784
+ )
785
+ .pay.ToContract(
786
+ cdpUtxo.address,
787
+ {
788
+ kind: 'inline',
789
+ value: serialiseCdpDatum({
790
+ ...cdpDatum,
791
+ mintedAmt: cdpDatum.mintedAmt + mintedAmountChange,
792
+ cdpFees: {
793
+ ActiveCDPInterestTracking: {
794
+ lastSettled: currentTime,
795
+ unitaryInterestSnapshot:
796
+ calculateUnitaryInterestSinceOracleLastUpdated(
797
+ currentTime,
798
+ interestOracleDatum,
799
+ ) + interestOracleDatum.unitaryInterest,
800
+ },
801
+ },
802
+ }),
803
+ },
804
+ addAssets(
805
+ cdpUtxo.assets,
806
+ mkAssetsOf(cdpDatum.collateralAsset, collateralAdjustment),
807
+ ),
808
+ );
809
+
810
+ if (!cdpDatum.cdpOwner) {
811
+ throw new Error('Expected active CDP');
812
+ }
813
+
814
+ tx.addSignerKey(toHex(cdpDatum.cdpOwner));
815
+
816
+ const iAssetAc = {
817
+ currencySymbol: fromHex(
818
+ sysParams.cdpParams.cdpAssetSymbol.unCurrencySymbol,
819
+ ),
820
+ tokenName: iassetDatum.assetName,
821
+ };
822
+
823
+ if (mintedAmountChange !== 0n) {
824
+ const iassetTokensVal = mkAssetsOf(iAssetAc, mintedAmountChange);
825
+
826
+ tx.mintAssets(iassetTokensVal, Data.void());
827
+ }
828
+
829
+ if (interestAmt > 0n) {
830
+ await collectInterestTx(
831
+ mkAssetsOf(iAssetAc, interestAmt),
832
+ lucid,
833
+ sysParams,
834
+ tx,
835
+ interestCollectorOref,
836
+ );
837
+ }
838
+
839
+ if (treasuryFee > 0n) {
840
+ await treasuryFeeTx(
841
+ iAssetAc,
842
+ treasuryFee,
843
+ 0n,
844
+ lucid,
845
+ sysParams,
846
+ tx,
847
+ cdpOref,
848
+ treasuryOref,
849
+ );
850
+ }
851
+
852
+ return tx;
853
+ }