@indigo-labs/indigo-sdk 0.2.41 → 0.3.0

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 (201) hide show
  1. package/.github/workflows/ci.yml +4 -2
  2. package/dist/index.d.mts +3008 -2194
  3. package/dist/index.d.ts +3008 -2194
  4. package/dist/index.js +9827 -6194
  5. package/dist/index.mjs +8591 -4809
  6. package/package.json +14 -3
  7. package/src/contracts/cdp/helpers.ts +68 -72
  8. package/src/contracts/cdp/scripts.ts +50 -13
  9. package/src/contracts/cdp/transactions.ts +831 -545
  10. package/src/contracts/cdp/types-new.ts +256 -0
  11. package/src/contracts/cdp/types.ts +26 -144
  12. package/src/contracts/cdp-creator/scripts.ts +15 -9
  13. package/src/contracts/cdp-creator/types-new.ts +50 -0
  14. package/src/contracts/cdp-creator/types.ts +5 -31
  15. package/src/contracts/collector/scripts.ts +1 -1
  16. package/src/contracts/collector/transactions.ts +23 -13
  17. package/src/contracts/collector/types-new.ts +17 -0
  18. package/src/contracts/execute/scripts.ts +19 -10
  19. package/src/contracts/execute/types-new.ts +44 -0
  20. package/src/contracts/execute/types.ts +5 -38
  21. package/src/contracts/gov/helpers.ts +187 -51
  22. package/src/contracts/gov/scripts.ts +17 -10
  23. package/src/contracts/gov/transactions.ts +599 -271
  24. package/src/contracts/gov/types-new.ts +253 -100
  25. package/src/contracts/gov/types.ts +4 -71
  26. package/src/contracts/iasset/helpers.ts +172 -0
  27. package/src/contracts/iasset/scripts.ts +38 -0
  28. package/src/contracts/iasset/types.ts +154 -0
  29. package/src/contracts/initialize/actions.ts +768 -0
  30. package/src/contracts/initialize/helpers.ts +611 -36
  31. package/src/contracts/initialize/types.ts +102 -28
  32. package/src/contracts/interest-collection/helpers.ts +19 -0
  33. package/src/contracts/interest-collection/scripts.ts +44 -0
  34. package/src/contracts/interest-collection/transactions.ts +436 -0
  35. package/src/contracts/interest-collection/types-new.ts +50 -0
  36. package/src/contracts/interest-collection/types.ts +26 -0
  37. package/src/contracts/interest-oracle/helpers.ts +2 -30
  38. package/src/contracts/interest-oracle/scripts.ts +1 -1
  39. package/src/contracts/interest-oracle/transactions.ts +21 -16
  40. package/src/contracts/interest-oracle/types-new.ts +32 -0
  41. package/src/contracts/interest-oracle/types.ts +1 -40
  42. package/src/contracts/one-shot/transactions.ts +1 -2
  43. package/src/contracts/poll/helpers.ts +5 -23
  44. package/src/contracts/poll/scripts.ts +12 -13
  45. package/src/contracts/poll/types-poll-manager.ts +1 -19
  46. package/src/contracts/poll/types-poll-new.ts +170 -0
  47. package/src/contracts/poll/types-poll-shard.ts +2 -24
  48. package/src/contracts/price-oracle/helpers.ts +1 -4
  49. package/src/contracts/price-oracle/scripts.ts +3 -8
  50. package/src/contracts/price-oracle/transactions.ts +32 -25
  51. package/src/contracts/price-oracle/types-new.ts +50 -0
  52. package/src/contracts/price-oracle/types.ts +2 -36
  53. package/src/contracts/pyth-feed/helpers.ts +58 -0
  54. package/src/contracts/pyth-feed/scripts.ts +15 -0
  55. package/src/contracts/pyth-feed/types.ts +181 -0
  56. package/src/contracts/rob/helpers.ts +405 -0
  57. package/src/contracts/rob/scripts.ts +35 -0
  58. package/src/contracts/rob/transactions.ts +410 -0
  59. package/src/contracts/rob/types-new.ts +128 -0
  60. package/src/contracts/rob/types.ts +16 -0
  61. package/src/contracts/rob-leverage/helpers.ts +424 -0
  62. package/src/contracts/{leverage → rob-leverage}/transactions.ts +68 -48
  63. package/src/contracts/stability-pool/helpers.ts +714 -230
  64. package/src/contracts/stability-pool/scripts.ts +20 -15
  65. package/src/contracts/stability-pool/transactions.ts +625 -495
  66. package/src/contracts/stability-pool/types-new.ts +237 -100
  67. package/src/contracts/stability-pool/types.ts +5 -22
  68. package/src/contracts/stableswap/helpers.ts +22 -0
  69. package/src/contracts/stableswap/scripts.ts +37 -0
  70. package/src/contracts/stableswap/transactions.ts +647 -0
  71. package/src/contracts/stableswap/types-new.ts +131 -0
  72. package/src/contracts/stableswap/types.ts +17 -0
  73. package/src/contracts/staking/helpers.ts +49 -34
  74. package/src/contracts/staking/scripts.ts +1 -1
  75. package/src/contracts/staking/transactions.ts +85 -130
  76. package/src/contracts/staking/types-new.ts +60 -28
  77. package/src/contracts/staking/types.ts +1 -28
  78. package/src/contracts/treasury/helpers.ts +21 -0
  79. package/src/contracts/treasury/scripts.ts +16 -26
  80. package/src/contracts/treasury/transactions.ts +256 -27
  81. package/src/contracts/treasury/types-new.ts +69 -0
  82. package/src/contracts/treasury/types.ts +2 -43
  83. package/src/contracts/version-registry/scripts.ts +2 -2
  84. package/src/contracts/version-registry/types-new.ts +6 -7
  85. package/src/index.ts +37 -20
  86. package/src/scripts/auth-token-policy.ts +3 -2
  87. package/src/scripts/iasset-policy.ts +3 -2
  88. package/src/types/evolution-schema-options.ts +3 -3
  89. package/src/types/generic.ts +17 -89
  90. package/src/types/multisig.ts +48 -0
  91. package/src/types/on-chain-decimal.ts +14 -7
  92. package/src/types/rational.ts +61 -0
  93. package/src/types/system-params.ts +237 -41
  94. package/src/utils/array-utils.ts +70 -1
  95. package/src/utils/bigint-utils.ts +12 -0
  96. package/src/utils/indigo-helpers.ts +8 -10
  97. package/src/utils/lucid-utils.ts +47 -40
  98. package/src/utils/oracle-helpers.ts +62 -0
  99. package/src/utils/pyth/decode.ts +223 -0
  100. package/src/utils/pyth/encode.ts +262 -0
  101. package/src/utils/pyth/index.ts +14 -0
  102. package/src/utils/pyth/types.ts +87 -0
  103. package/src/validators/always-succeed-validator.ts +6 -0
  104. package/src/validators/cdp-creator-validator.ts +2 -2
  105. package/src/validators/cdp-redeem-validator.ts +7 -0
  106. package/src/validators/cdp-validator.ts +2 -2
  107. package/src/validators/collector-validator.ts +2 -2
  108. package/src/validators/execute-validator.ts +2 -2
  109. package/src/validators/governance-validator.ts +2 -2
  110. package/src/validators/iasset-validator.ts +7 -0
  111. package/src/validators/interest-collection-validator.ts +7 -0
  112. package/src/validators/interest-oracle-validator.ts +2 -2
  113. package/src/validators/poll-manager-validator.ts +2 -2
  114. package/src/validators/poll-shard-validator.ts +2 -2
  115. package/src/validators/price-oracle-validator.ts +7 -0
  116. package/src/validators/pyth-feed-validator.ts +7 -0
  117. package/src/validators/rob-validator.ts +7 -0
  118. package/src/validators/stability-pool-validator.ts +2 -2
  119. package/src/validators/stableswap-validator.ts +7 -0
  120. package/src/validators/staking-validator.ts +2 -2
  121. package/src/validators/treasury-validator.ts +2 -2
  122. package/src/validators/version-record-policy.ts +2 -2
  123. package/src/validators/version-registry-validator.ts +2 -2
  124. package/tests/always-succeed/script.ts +7 -0
  125. package/tests/bigint-utils.test.ts +41 -0
  126. package/tests/cdp/actions.ts +611 -0
  127. package/tests/cdp/cdp-helpers.ts +55 -0
  128. package/tests/cdp/cdp-queries.ts +440 -0
  129. package/tests/cdp/cdp.test.ts +6087 -0
  130. package/tests/cdp/transactions-mutated.ts +1729 -0
  131. package/tests/data/system-params.json +177 -34
  132. package/tests/datums.test.ts +209 -210
  133. package/tests/endpoints/initialize.ts +68 -0
  134. package/tests/endpoints/interest-collector.ts +37 -0
  135. package/tests/endpoints/treasury.ts +70 -0
  136. package/tests/gov/actions.ts +406 -0
  137. package/tests/gov/gov.test.ts +4450 -0
  138. package/tests/{queries → gov}/governance-queries.ts +6 -3
  139. package/tests/hash-checks.test.ts +38 -11
  140. package/tests/indigo-test-helpers.ts +100 -0
  141. package/tests/initialize.test.ts +61 -9
  142. package/tests/interest-collection/interest-collection.test.ts +892 -0
  143. package/tests/interest-collection/interest-collector-queries.ts +49 -0
  144. package/tests/interest-collection/transactions-mutated.ts +260 -0
  145. package/tests/interest-oracle.test.ts +43 -35
  146. package/tests/mock/assets-mock.ts +234 -23
  147. package/tests/mock/protocol-params-mock.ts +21 -0
  148. package/tests/price-oracle/actions.ts +163 -0
  149. package/tests/price-oracle/price-oracle-queries.ts +12 -0
  150. package/tests/price-oracle/price-oracle.test.ts +240 -0
  151. package/tests/price-oracle/transactions-mutated.ts +62 -0
  152. package/tests/pyth/endpoints.ts +96 -0
  153. package/tests/pyth/helpers.ts +37 -0
  154. package/tests/pyth/pyth-encoding.test.ts +376 -0
  155. package/tests/pyth/pyth-indigo.test.ts +509 -0
  156. package/tests/pyth/pyth.test.ts +300 -0
  157. package/tests/queries/execute-queries.ts +6 -5
  158. package/tests/queries/iasset-queries.ts +175 -5
  159. package/tests/queries/interest-oracle-queries.ts +4 -2
  160. package/tests/queries/poll-queries.ts +8 -9
  161. package/tests/queries/stability-pool-queries.ts +95 -48
  162. package/tests/queries/staking-queries.ts +4 -2
  163. package/tests/queries/treasury-queries.ts +80 -5
  164. package/tests/rob/actions.ts +58 -0
  165. package/tests/{lrp-leverage.test.ts → rob/rob-leverage.test.ts} +393 -296
  166. package/tests/rob/rob-queries.ts +95 -0
  167. package/tests/rob/rob.test.ts +3762 -0
  168. package/tests/rob/transactions-mutated.ts +853 -0
  169. package/tests/script-size.test.ts +240 -0
  170. package/tests/setup.ts +135 -0
  171. package/tests/stability-pool/actions.ts +210 -0
  172. package/tests/stability-pool.test.ts +5469 -666
  173. package/tests/stableswap/stableswap-actions.ts +84 -0
  174. package/tests/stableswap/stableswap-queries.ts +89 -0
  175. package/tests/stableswap/stableswap.test.ts +3891 -0
  176. package/tests/stableswap/transactions-mutated.ts +348 -0
  177. package/tests/staking.test.ts +82 -99
  178. package/tests/test-helpers.ts +58 -11
  179. package/tests/treasury.test.ts +242 -0
  180. package/tests/utils/asserts.ts +74 -0
  181. package/tests/utils/benchmark-utils.ts +81 -0
  182. package/tests/utils/index.ts +122 -4
  183. package/tsconfig.json +9 -1
  184. package/vitest.config.ts +3 -1
  185. package/src/contracts/collector/types.ts +0 -16
  186. package/src/contracts/initialize/transactions.ts +0 -891
  187. package/src/contracts/leverage/helpers.ts +0 -424
  188. package/src/contracts/lrp/helpers.ts +0 -294
  189. package/src/contracts/lrp/scripts.ts +0 -27
  190. package/src/contracts/lrp/transactions.ts +0 -250
  191. package/src/contracts/lrp/types.ts +0 -131
  192. package/src/contracts/poll/types-poll.ts +0 -88
  193. package/src/contracts/vesting/helpers.ts +0 -218
  194. package/src/utils/value-helpers.ts +0 -37
  195. package/src/validators/lrp-validator.ts +0 -7
  196. package/tests/cdp.test.ts +0 -1528
  197. package/tests/gov.test.ts +0 -2011
  198. package/tests/lrp.test.ts +0 -673
  199. package/tests/queries/cdp-queries.ts +0 -220
  200. package/tests/queries/lrp-queries.ts +0 -76
  201. 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
+ }