@indigo-labs/indigo-sdk 0.5.5 → 0.5.6

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 (204) hide show
  1. package/package.json +11 -1
  2. package/.claude/settings.local.json +0 -7
  3. package/.github/workflows/ci.yml +0 -66
  4. package/.husky/pre-commit +0 -1
  5. package/.nvmrc +0 -1
  6. package/.prettierignore +0 -1
  7. package/.prettierrc +0 -6
  8. package/eslint.config.mjs +0 -42
  9. package/scripts/bench.sh +0 -62
  10. package/scripts/run-repeat.sh +0 -22
  11. package/src/contracts/cdp/helpers.ts +0 -173
  12. package/src/contracts/cdp/scripts.ts +0 -70
  13. package/src/contracts/cdp/transactions.ts +0 -1584
  14. package/src/contracts/cdp/types-new.ts +0 -277
  15. package/src/contracts/cdp/types.ts +0 -43
  16. package/src/contracts/cdp-creator/queries.ts +0 -30
  17. package/src/contracts/cdp-creator/scripts.ts +0 -45
  18. package/src/contracts/cdp-creator/types-new.ts +0 -50
  19. package/src/contracts/cdp-creator/types.ts +0 -24
  20. package/src/contracts/collector/scripts.ts +0 -32
  21. package/src/contracts/collector/transactions.ts +0 -50
  22. package/src/contracts/collector/types-new.ts +0 -17
  23. package/src/contracts/execute/scripts.ts +0 -57
  24. package/src/contracts/execute/types-new.ts +0 -44
  25. package/src/contracts/execute/types.ts +0 -24
  26. package/src/contracts/gov/helpers.ts +0 -351
  27. package/src/contracts/gov/scripts.ts +0 -41
  28. package/src/contracts/gov/transactions.ts +0 -1607
  29. package/src/contracts/gov/types-new.ts +0 -268
  30. package/src/contracts/gov/types.ts +0 -22
  31. package/src/contracts/iasset/helpers.ts +0 -170
  32. package/src/contracts/iasset/queries.ts +0 -102
  33. package/src/contracts/iasset/scripts.ts +0 -38
  34. package/src/contracts/iasset/types.ts +0 -154
  35. package/src/contracts/initialize/actions.ts +0 -789
  36. package/src/contracts/initialize/helpers.ts +0 -616
  37. package/src/contracts/initialize/types.ts +0 -116
  38. package/src/contracts/interest-collection/helpers.ts +0 -19
  39. package/src/contracts/interest-collection/queries.ts +0 -66
  40. package/src/contracts/interest-collection/scripts.ts +0 -44
  41. package/src/contracts/interest-collection/transactions.ts +0 -433
  42. package/src/contracts/interest-collection/types-new.ts +0 -50
  43. package/src/contracts/interest-collection/types.ts +0 -26
  44. package/src/contracts/interest-oracle/helpers.ts +0 -61
  45. package/src/contracts/interest-oracle/scripts.ts +0 -18
  46. package/src/contracts/interest-oracle/transactions.ts +0 -151
  47. package/src/contracts/interest-oracle/types-new.ts +0 -32
  48. package/src/contracts/interest-oracle/types.ts +0 -16
  49. package/src/contracts/one-shot/scripts.ts +0 -12
  50. package/src/contracts/one-shot/transactions.ts +0 -66
  51. package/src/contracts/one-shot/types.ts +0 -22
  52. package/src/contracts/poll/helpers.ts +0 -37
  53. package/src/contracts/poll/scripts.ts +0 -71
  54. package/src/contracts/poll/types-poll-manager.ts +0 -20
  55. package/src/contracts/poll/types-poll-new.ts +0 -196
  56. package/src/contracts/poll/types-poll-shard.ts +0 -16
  57. package/src/contracts/price-oracle/helpers.ts +0 -30
  58. package/src/contracts/price-oracle/scripts.ts +0 -18
  59. package/src/contracts/price-oracle/transactions.ts +0 -115
  60. package/src/contracts/price-oracle/types-new.ts +0 -50
  61. package/src/contracts/price-oracle/types.ts +0 -16
  62. package/src/contracts/pyth-feed/helpers.ts +0 -82
  63. package/src/contracts/pyth-feed/scripts.ts +0 -15
  64. package/src/contracts/pyth-feed/types.ts +0 -181
  65. package/src/contracts/rob/helpers.ts +0 -666
  66. package/src/contracts/rob/scripts.ts +0 -35
  67. package/src/contracts/rob/transactions.ts +0 -423
  68. package/src/contracts/rob/types-new.ts +0 -128
  69. package/src/contracts/rob/types.ts +0 -16
  70. package/src/contracts/rob-leverage/helpers.ts +0 -422
  71. package/src/contracts/rob-leverage/transactions.ts +0 -368
  72. package/src/contracts/stability-pool/helpers.ts +0 -798
  73. package/src/contracts/stability-pool/queries.ts +0 -132
  74. package/src/contracts/stability-pool/scripts.ts +0 -51
  75. package/src/contracts/stability-pool/transactions.ts +0 -921
  76. package/src/contracts/stability-pool/types-new.ts +0 -385
  77. package/src/contracts/stability-pool/types.ts +0 -25
  78. package/src/contracts/stableswap/helpers.ts +0 -507
  79. package/src/contracts/stableswap/scripts.ts +0 -37
  80. package/src/contracts/stableswap/transactions.ts +0 -475
  81. package/src/contracts/stableswap/types-new.ts +0 -131
  82. package/src/contracts/stableswap/types.ts +0 -17
  83. package/src/contracts/staking/helpers.ts +0 -136
  84. package/src/contracts/staking/scripts.ts +0 -41
  85. package/src/contracts/staking/transactions.ts +0 -349
  86. package/src/contracts/staking/types-new.ts +0 -137
  87. package/src/contracts/staking/types.ts +0 -17
  88. package/src/contracts/treasury/helpers.ts +0 -21
  89. package/src/contracts/treasury/queries.ts +0 -100
  90. package/src/contracts/treasury/scripts.ts +0 -27
  91. package/src/contracts/treasury/transactions.ts +0 -334
  92. package/src/contracts/treasury/types-new.ts +0 -69
  93. package/src/contracts/treasury/types.ts +0 -14
  94. package/src/contracts/version-registry/scripts.ts +0 -29
  95. package/src/contracts/version-registry/types-new.ts +0 -18
  96. package/src/contracts/version-registry/types.ts +0 -17
  97. package/src/index.ts +0 -99
  98. package/src/scripts/always-fail-validator.ts +0 -7
  99. package/src/scripts/auth-token-policy.ts +0 -24
  100. package/src/scripts/iasset-policy.ts +0 -23
  101. package/src/types/evolution-schema-options.ts +0 -16
  102. package/src/types/generic.ts +0 -52
  103. package/src/types/multisig.ts +0 -48
  104. package/src/types/on-chain-decimal.ts +0 -57
  105. package/src/types/rational.ts +0 -76
  106. package/src/types/system-params.ts +0 -463
  107. package/src/utils/array-utils.ts +0 -108
  108. package/src/utils/bigint-utils.ts +0 -35
  109. package/src/utils/helper-txs.ts +0 -31
  110. package/src/utils/indigo-helpers.ts +0 -17
  111. package/src/utils/lucid-utils.ts +0 -125
  112. package/src/utils/oracle-helpers.ts +0 -62
  113. package/src/utils/pyth/decode.ts +0 -223
  114. package/src/utils/pyth/encode.ts +0 -262
  115. package/src/utils/pyth/index.ts +0 -14
  116. package/src/utils/pyth/types.ts +0 -87
  117. package/src/utils/time-helpers.ts +0 -4
  118. package/src/utils/utils.ts +0 -25
  119. package/src/validators/always-succeed-validator.ts +0 -6
  120. package/src/validators/cdp-creator-validator.ts +0 -7
  121. package/src/validators/cdp-redeem-validator.ts +0 -7
  122. package/src/validators/cdp-validator.ts +0 -7
  123. package/src/validators/collector-validator.ts +0 -7
  124. package/src/validators/execute-validator.ts +0 -7
  125. package/src/validators/governance-validator.ts +0 -7
  126. package/src/validators/iasset-validator.ts +0 -7
  127. package/src/validators/interest-collection-validator.ts +0 -7
  128. package/src/validators/interest-oracle-validator.ts +0 -7
  129. package/src/validators/one-shot-policy.ts +0 -7
  130. package/src/validators/poll-manager-validator.ts +0 -7
  131. package/src/validators/poll-shard-validator.ts +0 -7
  132. package/src/validators/price-oracle-validator.ts +0 -7
  133. package/src/validators/pyth-feed-validator.ts +0 -7
  134. package/src/validators/rob-validator.ts +0 -7
  135. package/src/validators/stability-pool-validator.ts +0 -7
  136. package/src/validators/stableswap-validator.ts +0 -7
  137. package/src/validators/staking-validator.ts +0 -7
  138. package/src/validators/treasury-validator.ts +0 -7
  139. package/src/validators/version-record-policy.ts +0 -7
  140. package/src/validators/version-registry-validator.ts +0 -7
  141. package/tests/always-succeed/script.ts +0 -7
  142. package/tests/array-utils.test.ts +0 -92
  143. package/tests/bigint-utils.test.ts +0 -41
  144. package/tests/cdp/actions.ts +0 -680
  145. package/tests/cdp/cdp-helpers.ts +0 -55
  146. package/tests/cdp/cdp-queries.ts +0 -423
  147. package/tests/cdp/cdp.test.ts +0 -6730
  148. package/tests/cdp/transactions-mutated.ts +0 -1733
  149. package/tests/data/system-params.json +0 -1155
  150. package/tests/datums.test.ts +0 -302
  151. package/tests/endpoints/initialize.ts +0 -78
  152. package/tests/endpoints/interest-collector.ts +0 -37
  153. package/tests/endpoints/treasury.ts +0 -70
  154. package/tests/gov/actions.ts +0 -381
  155. package/tests/gov/gov.test.ts +0 -5147
  156. package/tests/gov/governance-queries.ts +0 -37
  157. package/tests/hash-checks.test.ts +0 -112
  158. package/tests/indigo-test-helpers.ts +0 -99
  159. package/tests/initialize.test.ts +0 -79
  160. package/tests/interest-calculations.test.ts +0 -120
  161. package/tests/interest-collection/interest-collection.test.ts +0 -843
  162. package/tests/interest-collection/transactions-mutated.ts +0 -260
  163. package/tests/interest-oracle.test.ts +0 -93
  164. package/tests/mock/assets-mock.ts +0 -243
  165. package/tests/mock/protocol-params-mock.ts +0 -21
  166. package/tests/price-oracle/actions.ts +0 -161
  167. package/tests/price-oracle/price-oracle-queries.ts +0 -12
  168. package/tests/price-oracle/price-oracle.test.ts +0 -228
  169. package/tests/price-oracle/transactions-mutated.ts +0 -59
  170. package/tests/pyth/endpoints.ts +0 -96
  171. package/tests/pyth/helpers.ts +0 -37
  172. package/tests/pyth/pyth-encoding.test.ts +0 -376
  173. package/tests/pyth/pyth-feeds.test.ts +0 -943
  174. package/tests/pyth/pyth-indigo.test.ts +0 -505
  175. package/tests/pyth/pyth.test.ts +0 -299
  176. package/tests/queries/collector-queries.ts +0 -27
  177. package/tests/queries/execute-queries.ts +0 -47
  178. package/tests/queries/iasset-queries.ts +0 -149
  179. package/tests/queries/interest-oracle-queries.ts +0 -12
  180. package/tests/queries/poll-queries.ts +0 -97
  181. package/tests/queries/staking-queries.ts +0 -54
  182. package/tests/rob/actions.ts +0 -56
  183. package/tests/rob/rob-leverage.test.ts +0 -2555
  184. package/tests/rob/rob-queries.ts +0 -95
  185. package/tests/rob/rob.test.ts +0 -3677
  186. package/tests/rob/transactions-mutated.ts +0 -844
  187. package/tests/script-size.test.ts +0 -240
  188. package/tests/setup.ts +0 -135
  189. package/tests/stability-pool/actions.ts +0 -229
  190. package/tests/stability-pool.test.ts +0 -6491
  191. package/tests/stableswap/stableswap-actions.ts +0 -83
  192. package/tests/stableswap/stableswap-queries.ts +0 -98
  193. package/tests/stableswap/stableswap.test.ts +0 -4471
  194. package/tests/stableswap/transactions-mutated.ts +0 -348
  195. package/tests/staking.test.ts +0 -172
  196. package/tests/test-helpers.ts +0 -94
  197. package/tests/treasury/actions.ts +0 -67
  198. package/tests/treasury/treasury.test.ts +0 -320
  199. package/tests/utils/asserts.ts +0 -87
  200. package/tests/utils/benchmark-utils.ts +0 -130
  201. package/tests/utils/index.ts +0 -168
  202. package/tsconfig.build.json +0 -4
  203. package/tsconfig.json +0 -27
  204. package/vitest.config.ts +0 -11
@@ -1,666 +0,0 @@
1
- import {
2
- addAssets,
3
- Assets,
4
- fromHex,
5
- toHex,
6
- TxBuilder,
7
- UTxO,
8
- } from '@lucid-evolution/lucid';
9
- import {
10
- RobDatum,
11
- RobOrderType,
12
- parseRobDatumOrThrow,
13
- serialiseRobDatum,
14
- serialiseRobRedeemer,
15
- } from './types-new';
16
- import { calculateFeeFromRatio } from '../../utils/indigo-helpers';
17
- import {
18
- BigIntOrd,
19
- fromDecimal,
20
- sum,
21
- zeroNegatives,
22
- } from '../../utils/bigint-utils';
23
- import {
24
- readonlyArray as RA,
25
- array as A,
26
- function as F,
27
- option as O,
28
- ord as Ord,
29
- } from 'fp-ts';
30
- import { SystemParams } from '../../types/system-params';
31
- import { match, P } from 'ts-pattern';
32
- import { getInlineDatumOrThrow } from '../../utils/lucid-utils';
33
- import {
34
- adaAssetClass,
35
- AssetClass,
36
- assetClassValueOf,
37
- isSameAssetClass,
38
- lovelacesAmt,
39
- mkAssetsOf,
40
- } from '@3rd-eye-labs/cardano-offchain-common';
41
- import {
42
- Rational,
43
- rationalFloor,
44
- rationalFromInt,
45
- rationalMul,
46
- rationalToFloat,
47
- } from '../../types/rational';
48
- import { insertSorted, shuffle } from '../../utils/array-utils';
49
- import { iassetValueOfCollateral } from '../cdp/helpers';
50
- import { OracleIdx } from '../price-oracle/types-new';
51
- import Decimal from 'decimal.js';
52
-
53
- export const MIN_ROB_COLLATERAL_AMT = 3_000_000n;
54
-
55
- /**
56
- * The maximum of redemptions for a Tx that is doing only sell order redemptions.
57
- * Based on the benchmarks.
58
- */
59
- export const MAX_SELL_ROB_REDEMPTIONS_COUNT = 18;
60
- /**
61
- * The maximum of redemptions for a Tx that is doing only buy order redemptions.
62
- * Based on the benchmarks.
63
- */
64
- export const MAX_BUY_ROB_REDEMPTIONS_COUNT = 20;
65
-
66
- /**
67
- * Helper for ROB redemptions. A redeemer is selling iAssets against
68
- * a buy order, i.e. buying a collateral asset.
69
- * The return is the amount of collateral asset he buys.
70
- */
71
- export function calculatePurchaseAmtWhenRobBuyOrder(
72
- sellIassetAmt: bigint,
73
- redemptionReimbursementRatio: Rational,
74
- price: Rational,
75
- ): bigint {
76
- const reimbursementIAsset = calculateFeeFromRatio(
77
- redemptionReimbursementRatio,
78
- sellIassetAmt,
79
- );
80
-
81
- const collateralForRedemption = rationalFloor(
82
- rationalMul(rationalFromInt(sellIassetAmt - reimbursementIAsset), price),
83
- );
84
-
85
- return collateralForRedemption;
86
- }
87
-
88
- /**
89
- * A redeemer is purchasing given collateral amount against buy order.
90
- * Calculate what is the amount of iAsset the user sells/spends.
91
- */
92
- export function calculateSpendAmtWhenRobBuyOrder(
93
- purchaseCollateralAmt: bigint,
94
- redemptionReimbursementRatio: Rational,
95
- price: Rational,
96
- ): bigint {
97
- const priceDecimal = Decimal(price.numerator).div(price.denominator);
98
- const reimbRatio = Decimal(redemptionReimbursementRatio.numerator).div(
99
- redemptionReimbursementRatio.denominator,
100
- );
101
-
102
- // TODO: make corrections here in case we can be ceiling this number instead.
103
- // We want to be flooring here so that we don't go over the collateral to spend.
104
- // Flooring multiple times is necessary here otherwise we could go over the collateral available.
105
- // iassets = floor(collateral / price) / floor(1 - reimbursement fee)
106
- return fromDecimal(
107
- Decimal(purchaseCollateralAmt)
108
- .div(priceDecimal)
109
- .floor()
110
- .div(Decimal(1).minus(reimbRatio))
111
- .floor(),
112
- );
113
- }
114
-
115
- /**
116
- * Helper for ROB redemptions. A redeemer is selling collateral against
117
- * a sell order, i.e. buying iassets.
118
- * The return is the amount of iassets he buys.
119
- */
120
- export function calculatePurchaseAmtWhenRobSellOrder(
121
- sellCollateralAmt: bigint,
122
- redemptionReimbursementRatio: Rational,
123
- price: Rational,
124
- ): bigint {
125
- const reimbursementCollateral = calculateFeeFromRatio(
126
- redemptionReimbursementRatio,
127
- sellCollateralAmt,
128
- );
129
-
130
- const redeemedIAssetAmt = iassetValueOfCollateral(
131
- sellCollateralAmt - reimbursementCollateral,
132
- price,
133
- );
134
-
135
- return redeemedIAssetAmt;
136
- }
137
-
138
- /**
139
- * A redeemer is purchasing given iasset amount against sell order.
140
- * Calculate what is the amount of collateral the user sells/spends.
141
- */
142
- export function calculateSpendAmtWhenRobSellOrder(
143
- purchaseIassetAmt: bigint,
144
- redemptionReimbursementRatio: Rational,
145
- price: Rational,
146
- ): bigint {
147
- const priceDecimal = Decimal(price.numerator).div(price.denominator);
148
- const reimbRatio = Decimal(redemptionReimbursementRatio.numerator).div(
149
- redemptionReimbursementRatio.denominator,
150
- );
151
-
152
- // collateral = floor(iasset * price) / floor(1 - reimbursement fee)
153
- return fromDecimal(
154
- Decimal(purchaseIassetAmt)
155
- .mul(priceDecimal)
156
- .floor()
157
- .div(Decimal(1).minus(reimbRatio))
158
- .floor(),
159
- );
160
- }
161
-
162
- /**
163
- * The amount of collateral asset available in the ROB when buy order. In case of ADA, take
164
- * into account the min UTXO collateral.
165
- */
166
- export function robCollateralAmtToSpend(
167
- robAssets: Assets,
168
- robOrderType: RobOrderType,
169
- ): bigint {
170
- return match(robOrderType)
171
- .returnType<bigint>()
172
- .with({ BuyIAssetOrder: P.select() }, (content) => {
173
- if (isSameAssetClass(adaAssetClass, content.collateralAsset)) {
174
- return zeroNegatives(lovelacesAmt(robAssets) - MIN_ROB_COLLATERAL_AMT);
175
- } else {
176
- return assetClassValueOf(robAssets, content.collateralAsset);
177
- }
178
- })
179
- .otherwise(() => {
180
- throw new Error('Collateral to spend is relevant only for Buy orders.');
181
- });
182
- }
183
-
184
- /**
185
- * The amount if iassets available in ROB when sell order.
186
- */
187
- export function robIAssetAmtToSpend(
188
- robAssets: Assets,
189
- robOrderType: RobOrderType,
190
- /**
191
- * This has to be assetclass having policyID of Indigo iAssets,
192
- * and the asset name being the ROB datum iasset.
193
- */
194
- robIasset: AssetClass,
195
- ): bigint {
196
- return match(robOrderType)
197
- .returnType<bigint>()
198
- .with({ SellIAssetOrder: P.any }, (_) => {
199
- return assetClassValueOf(robAssets, robIasset);
200
- })
201
- .otherwise(() => {
202
- throw new Error('IAssets to spend is relevant only for Sell orders.');
203
- });
204
- }
205
-
206
- /**
207
- * Amount to spend from the ROB universal for Buy and sell orders.
208
- */
209
- export function robAmtToSpend(
210
- robAssets: Assets,
211
- robOrderType: RobOrderType,
212
- /**
213
- * This has to be assetclass having policyID of Indigo iAssets,
214
- * and the asset name being the ROB datum iasset.
215
- */
216
- robIasset: AssetClass,
217
- ): bigint {
218
- return match(robOrderType)
219
- .with({ BuyIAssetOrder: P.any }, () =>
220
- robCollateralAmtToSpend(robAssets, robOrderType),
221
- )
222
- .with({ SellIAssetOrder: P.any }, () =>
223
- robIAssetAmtToSpend(robAssets, robOrderType, robIasset),
224
- )
225
- .exhaustive();
226
- }
227
-
228
- type FilledResult = { asset: AssetClass; filledAmt: bigint };
229
-
230
- /**
231
- * The assets that have filled the order and are able to be claimed.
232
- */
233
- export function robBuyOrderFilledAssets(
234
- robAssets: Assets,
235
- robOrderType: RobOrderType,
236
- /**
237
- * This has to be assetclass having policyID of Indigo iAssets,
238
- * and the asset name being the ROB datum iasset.
239
- */
240
- robIasset: AssetClass,
241
- ): FilledResult {
242
- return match(robOrderType)
243
- .returnType<FilledResult>()
244
- .with({ BuyIAssetOrder: P.any }, () => {
245
- return {
246
- asset: robIasset,
247
- filledAmt: assetClassValueOf(robAssets, robIasset),
248
- };
249
- })
250
- .otherwise(() => {
251
- throw new Error('Expected only buy order.');
252
- });
253
- }
254
-
255
- /**
256
- * The assets that have filled the order and are able to be claimed.
257
- */
258
- export function robSellOrderFilledAssets(
259
- robAssets: Assets,
260
- robOrderType: RobOrderType,
261
- ): FilledResult[] {
262
- return match(robOrderType)
263
- .returnType<FilledResult[]>()
264
- .with({ SellIAssetOrder: P.select() }, (content) => {
265
- return content.allowedCollateralAssets.map(([asset, _]) => {
266
- return {
267
- asset: asset,
268
- filledAmt:
269
- assetClassValueOf(robAssets, asset) -
270
- (isSameAssetClass(asset, adaAssetClass)
271
- ? MIN_ROB_COLLATERAL_AMT
272
- : 0n),
273
- } satisfies FilledResult;
274
- });
275
- })
276
- .otherwise(() => {
277
- throw new Error('Expected only sell order.');
278
- });
279
- }
280
-
281
- export function robBuyOrderSummary(
282
- robAssets: Assets,
283
- robOrderType: RobOrderType,
284
- oraclePrice: Rational,
285
- ): {
286
- /**
287
- * The amount that can be spent from the ROB.
288
- */
289
- redeemableCollateral: bigint;
290
- /**
291
- * The amount paid to the ROB when everything redeemed.
292
- */
293
- payoutIAsset: bigint;
294
- } {
295
- const redeemable = robCollateralAmtToSpend(robAssets, robOrderType);
296
-
297
- // TODO: this is incorrect since it doesn't take into account the reimbursement ratio.
298
- const payoutAmt = iassetValueOfCollateral(redeemable, oraclePrice);
299
-
300
- return {
301
- redeemableCollateral: redeemable,
302
- payoutIAsset: payoutAmt,
303
- };
304
- }
305
-
306
- /**
307
- * In case it's applied to a sell order instead, it will throw an error.
308
- */
309
- export function isBuyOrderFullyRedeemed(
310
- robAssets: Assets,
311
- robOrderType: RobOrderType,
312
- oraclePrice: Rational,
313
- ): boolean {
314
- const summary = robBuyOrderSummary(robAssets, robOrderType, oraclePrice);
315
-
316
- return summary.redeemableCollateral <= 0n || summary.payoutIAsset <= 0n;
317
- }
318
-
319
- /**
320
- * Use the limit prices to decide fully redeemed.
321
- */
322
- export function isFullyRedeemed(
323
- robAssets: Assets,
324
- robOrderType: RobOrderType,
325
- /**
326
- * This has to be assetclass having policyID of Indigo iAssets,
327
- * and the asset name being the ROB datum iasset.
328
- */
329
- robIasset: AssetClass,
330
- ): boolean {
331
- return match(robOrderType)
332
- .returnType<boolean>()
333
- .with({ BuyIAssetOrder: P.select() }, (content) =>
334
- isBuyOrderFullyRedeemed(robAssets, robOrderType, content.maxPrice),
335
- )
336
-
337
- .with({ SellIAssetOrder: P.select() }, (content) => {
338
- const iassetToSpend = robIAssetAmtToSpend(
339
- robAssets,
340
- robOrderType,
341
- robIasset,
342
- );
343
-
344
- const payoutAmts = content.allowedCollateralAssets.map((c) =>
345
- rationalFloor(rationalMul(rationalFromInt(iassetToSpend), c[1])),
346
- );
347
-
348
- return (
349
- iassetToSpend <= 0n ||
350
- // When for every allowed collateral asset the payout would be 0
351
- payoutAmts.every((amt) => amt <= 0n)
352
- );
353
- })
354
- .exhaustive();
355
- }
356
-
357
- /**
358
- * Right now we allow multi redemptions when the collateral asset, iasset pair is the same.
359
- * The on-chain however should allow even other combinations.
360
- */
361
- export function buildRedemptionsTx(
362
- /**
363
- * The tuple represents the ROB UTXO and the amount to payout for a redemption. In case of buy order,
364
- * it's denominated in iAssets, in case of sell order, it's denominated in collateral asset.
365
- */
366
- redemptions: [UTxO, bigint][],
367
- iasset: Uint8Array<ArrayBufferLike>,
368
- collateralAsset: AssetClass,
369
- price: Rational,
370
- redemptionReimbursementRatio: Rational,
371
- sysParams: SystemParams,
372
- tx: TxBuilder,
373
- /**
374
- * The number of Tx outputs before these new ones.
375
- */
376
- txOutputsBeforeCount: bigint,
377
- collateralAssetRefInputIdx: bigint,
378
- iassetRefInputIdx: bigint,
379
- oracleIdx: OracleIdx,
380
- ): TxBuilder {
381
- return F.pipe(
382
- redemptions,
383
- A.reduceWithIndex<[UTxO, bigint], TxBuilder>(
384
- tx,
385
- (idx, acc, [robUtxo, payoutAmt]) => {
386
- const robDatum = parseRobDatumOrThrow(getInlineDatumOrThrow(robUtxo));
387
-
388
- if (toHex(robDatum.iasset) !== toHex(iasset)) {
389
- throw new Error('Only same iAsset');
390
- }
391
-
392
- const [robOutputVal, sellOrderAllowedAssetsIdx] = match(
393
- robDatum.orderType,
394
- )
395
- .returnType<[Assets, bigint]>()
396
- .with({ BuyIAssetOrder: P.select() }, (content) => {
397
- if (!isSameAssetClass(content.collateralAsset, collateralAsset)) {
398
- throw new Error('Only same collateral asset');
399
- }
400
-
401
- const payoutIAssetAmt = payoutAmt;
402
-
403
- const collateralForRedemption = calculatePurchaseAmtWhenRobBuyOrder(
404
- payoutIAssetAmt,
405
- redemptionReimbursementRatio,
406
- price,
407
- );
408
-
409
- const resultVal = addAssets(
410
- robUtxo.assets,
411
- mkAssetsOf(collateralAsset, -collateralForRedemption),
412
- mkAssetsOf(
413
- {
414
- currencySymbol: fromHex(
415
- sysParams.robParams.iassetPolicyId.unCurrencySymbol,
416
- ),
417
- tokenName: robDatum.iasset,
418
- },
419
- payoutIAssetAmt,
420
- ),
421
- );
422
-
423
- return [resultVal, 0n];
424
- })
425
- .with({ SellIAssetOrder: P.select() }, (content) => {
426
- const allowedAssetIdx = F.pipe(
427
- content.allowedCollateralAssets,
428
- RA.findIndex(([asset, _]) =>
429
- isSameAssetClass(asset, collateralAsset),
430
- ),
431
- O.getOrElse<number>(() => {
432
- throw new Error("Doesn't allow required collateral asset.");
433
- }),
434
- );
435
-
436
- const payoutCollateralAmt = payoutAmt;
437
-
438
- const redeemedIAssetAmt = calculatePurchaseAmtWhenRobSellOrder(
439
- payoutCollateralAmt,
440
- redemptionReimbursementRatio,
441
- price,
442
- );
443
-
444
- const resultVal = addAssets(
445
- robUtxo.assets,
446
- mkAssetsOf(collateralAsset, payoutCollateralAmt),
447
- mkAssetsOf(
448
- {
449
- currencySymbol: fromHex(
450
- sysParams.robParams.iassetPolicyId.unCurrencySymbol,
451
- ),
452
- tokenName: robDatum.iasset,
453
- },
454
- -redeemedIAssetAmt,
455
- ),
456
- );
457
-
458
- return [resultVal, BigInt(allowedAssetIdx)];
459
- })
460
- .exhaustive();
461
-
462
- if (lovelacesAmt(robOutputVal) < MIN_ROB_COLLATERAL_AMT) {
463
- throw new Error(
464
- 'Redeeming more than available or selected ROB was incorrectly initialised.',
465
- );
466
- }
467
-
468
- return acc
469
- .collectFrom([robUtxo], {
470
- kind: 'self',
471
- makeRedeemer: (ownIdx) =>
472
- serialiseRobRedeemer({
473
- Redeem: {
474
- ownInputIdx: ownIdx,
475
- collateralAssetRefInputIdx: collateralAssetRefInputIdx,
476
- iassetRefInputIdx: iassetRefInputIdx,
477
- continuingOutputIdx: txOutputsBeforeCount + BigInt(idx),
478
- sellOrderAllowedAssetsIdx: sellOrderAllowedAssetsIdx,
479
- priceOracleIdx: oracleIdx,
480
- },
481
- }),
482
- })
483
- .pay.ToContract(
484
- robUtxo.address,
485
- {
486
- kind: 'inline',
487
- value: serialiseRobDatum({
488
- ...robDatum,
489
- robRefInput: {
490
- outputIndex: BigInt(robUtxo.outputIndex),
491
- txHash: fromHex(robUtxo.txHash),
492
- },
493
- }),
494
- },
495
- robOutputVal,
496
- );
497
- },
498
- ),
499
- );
500
- }
501
-
502
- /**
503
- * Given all available LRP UTXOs, calculate total available collateral that can be redeemed.
504
- * Taking into account incorrectly initialised LRPs (without base collateral) and max number of ROBs.
505
- */
506
- export function calculateTotalCollateralForRedemption(
507
- iasset: Uint8Array<ArrayBufferLike>,
508
- collateralAsset: AssetClass,
509
- iassetPrice: Rational,
510
- allRobs: [UTxO, RobDatum][],
511
- /**
512
- * How many LRPs can be redeemed in a single Tx.
513
- */
514
- maxRobsInTx: number,
515
- ): bigint {
516
- return F.pipe(
517
- allRobs,
518
- A.filterMap(([utxo, datum]) => {
519
- const isCorrectOrder = match(datum.orderType)
520
- .returnType<boolean>()
521
- .with(
522
- { BuyIAssetOrder: P.select() },
523
- (content) =>
524
- isSameAssetClass(content.collateralAsset, collateralAsset) &&
525
- rationalToFloat(content.maxPrice) >= rationalToFloat(iassetPrice) &&
526
- !isBuyOrderFullyRedeemed(utxo.assets, datum.orderType, iassetPrice),
527
- )
528
- .otherwise(() => false);
529
-
530
- if (toHex(datum.iasset) !== toHex(iasset) || !isCorrectOrder) {
531
- return O.none;
532
- }
533
-
534
- // We constrained in the logic above that the ROB is a buy order and is not yet fully redeemed.
535
- const collateralToSpend = robCollateralAmtToSpend(
536
- utxo.assets,
537
- datum.orderType,
538
- );
539
-
540
- return O.some(collateralToSpend);
541
- }),
542
- // From largest to smallest
543
- A.sort(Ord.reverse(BigIntOrd)),
544
- // We can fit only this number of redemptions with CDP open into a single Tx.
545
- A.takeLeft(maxRobsInTx),
546
- sum,
547
- );
548
- }
549
-
550
- /**
551
- * Pick random subset from all the ROBs (it does the necessary filtering) satisfying the target collateral to spend.
552
- * It's relevant for BUY orders only.
553
- */
554
- export function randomRobsSubsetSatisfyingTargetCollateral(
555
- iasset: Uint8Array<ArrayBufferLike>,
556
- collateralAsset: AssetClass,
557
- targetCollateralToSpend: bigint,
558
- iassetPrice: Rational,
559
- allLrps: [UTxO, RobDatum][],
560
- /**
561
- * How many LRPs can be redeemed in a single Tx.
562
- */
563
- maxLrpsInTx: number,
564
- randomiseFn: (arr: [UTxO, RobDatum][]) => [UTxO, RobDatum][] = shuffle,
565
- ): [UTxO, RobDatum][] {
566
- if (
567
- targetCollateralToSpend <= 0n ||
568
- iassetValueOfCollateral(targetCollateralToSpend, iassetPrice) <= 0n
569
- ) {
570
- throw new Error('Must redeem and payout more than 0.');
571
- }
572
-
573
- const shuffled = randomiseFn(
574
- F.pipe(
575
- allLrps,
576
- A.filter(
577
- ([utxo, datum]) =>
578
- toHex(datum.iasset) === toHex(iasset) &&
579
- match(datum.orderType)
580
- .with(
581
- { BuyIAssetOrder: P.select() },
582
- (content) =>
583
- isSameAssetClass(collateralAsset, content.collateralAsset) &&
584
- rationalToFloat(content.maxPrice) >=
585
- rationalToFloat(iassetPrice),
586
- )
587
- // Only buy order types
588
- .otherwise(() => false) &&
589
- !isBuyOrderFullyRedeemed(utxo.assets, datum.orderType, iassetPrice),
590
- ),
591
- ),
592
- );
593
-
594
- // Sorted from highest to lowest by lovelaces to spend
595
- let result: [UTxO, RobDatum][] = [];
596
- let runningSum = 0n;
597
-
598
- for (let i = 0; i < shuffled.length; i++) {
599
- const element = shuffled[i];
600
-
601
- const lovelacesToSpend = robCollateralAmtToSpend(
602
- element[0].assets,
603
- element[1].orderType,
604
- );
605
-
606
- const remainingToRedeem = targetCollateralToSpend - runningSum;
607
- const remainingToPayout = iassetValueOfCollateral(
608
- remainingToRedeem,
609
- iassetPrice,
610
- );
611
-
612
- // When we can't add a new redemption because otherwise there would be no payout.
613
- // Try to replace the smallest collected with a following larger one when available.
614
- if (result.length > 0 && remainingToPayout <= 0n) {
615
- const last = result[result.length - 1];
616
-
617
- const lastSummary = robBuyOrderSummary(
618
- last[0].assets,
619
- last[1].orderType,
620
- iassetPrice,
621
- );
622
-
623
- // Pop the smallest collected when the current is larger.
624
- if (lastSummary.redeemableCollateral < lovelacesToSpend) {
625
- result.pop()!;
626
- runningSum -= lastSummary.redeemableCollateral;
627
- } else {
628
- continue;
629
- }
630
- }
631
-
632
- result = insertSorted(
633
- result,
634
- element,
635
- Ord.contramap<bigint, [UTxO, RobDatum]>(
636
- ([utxo, dat]) => robCollateralAmtToSpend(utxo.assets, dat.orderType),
637
- // From highest to lowest
638
- )(Ord.reverse(BigIntOrd)),
639
- );
640
- runningSum += lovelacesToSpend;
641
-
642
- // When more items than max allowed, pop the one with smallest value
643
- if (result.length > maxLrpsInTx) {
644
- const popped = result.pop()!;
645
- runningSum -= robCollateralAmtToSpend(
646
- popped[0].assets,
647
- popped[1].orderType,
648
- );
649
- }
650
-
651
- if (runningSum >= targetCollateralToSpend) {
652
- return result;
653
- }
654
- }
655
-
656
- const remainingToSpend = targetCollateralToSpend - runningSum;
657
-
658
- if (
659
- remainingToSpend > 0n &&
660
- iassetValueOfCollateral(remainingToSpend, iassetPrice) > 0n
661
- ) {
662
- throw new Error("Couldn't achieve target lovelaces");
663
- }
664
-
665
- return result;
666
- }
@@ -1,35 +0,0 @@
1
- import { applyParamsToScript, SpendingValidator } from '@lucid-evolution/lucid';
2
- import { castRobParams, RobParams } from './types';
3
- import {
4
- fromSystemParamsAssetLucid,
5
- RobParamsSP,
6
- } from '../../types/system-params';
7
- import { _robValidator } from '../../validators/rob-validator';
8
-
9
- export const mkRobValidator = (params: RobParams): SpendingValidator => {
10
- return {
11
- type: 'PlutusV3',
12
- script: applyParamsToScript(_robValidator.cborHex, [castRobParams(params)]),
13
- };
14
- };
15
-
16
- export const mkRobValidatorFromSP = (
17
- params: RobParamsSP,
18
- ): SpendingValidator => {
19
- return {
20
- type: 'PlutusV3',
21
- script: applyParamsToScript(_robValidator.cborHex, [
22
- castRobParams({
23
- versionRecordToken: fromSystemParamsAssetLucid(
24
- params.versionRecordToken,
25
- ),
26
- iassetValHash: params.iassetValHash,
27
- iassetAuthToken: fromSystemParamsAssetLucid(params.iassetAuthToken),
28
- collateralAssetAuthToken: fromSystemParamsAssetLucid(
29
- params.collateralAssetAuthToken,
30
- ),
31
- iassetPolicyId: params.iassetPolicyId.unCurrencySymbol,
32
- }),
33
- ]),
34
- };
35
- };