@indigo-labs/indigo-sdk 0.3.10 → 0.3.12

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.
@@ -51,6 +51,7 @@ export async function findRandomTreasuryUtxoWithAsset(
51
51
  lucid: LucidEvolution,
52
52
  sysParams: SystemParams,
53
53
  asset: AssetClass,
54
+ max_number_of_assets: bigint = 2n,
54
55
  ): Promise<UTxO> {
55
56
  // We need to consider both with staking credential and without.
56
57
  const treasuryUtxos = await lucid.utxosAtWithUnit(
@@ -58,8 +59,12 @@ export async function findRandomTreasuryUtxoWithAsset(
58
59
  assetClassToUnit(asset),
59
60
  );
60
61
 
62
+ const validTreasuryUtxos = treasuryUtxos.filter(
63
+ (utxo) => Object.keys(utxo.assets).length <= max_number_of_assets,
64
+ );
65
+
61
66
  return F.pipe(
62
- O.fromNullable(getRandomElement(treasuryUtxos)),
67
+ O.fromNullable(getRandomElement(validTreasuryUtxos)),
63
68
  O.match(() => {
64
69
  throw new Error('Expected some treasury UTXOs.');
65
70
  }, F.identity),
@@ -1,4 +1,4 @@
1
- import { beforeEach, expect, test } from 'vitest';
1
+ import { assert, beforeEach, expect, test } from 'vitest';
2
2
  import {
3
3
  LucidContext,
4
4
  repeat,
@@ -757,7 +757,8 @@ describe('Stability pool', () => {
757
757
  // Send funds to user4 so liquidation is performed from a clean address.
758
758
  await sendValueTo(
759
759
  context.users.user4.address,
760
- mkAssetsOf(collateralAssetA, LIQUIDATED_COLLATERAL),
760
+ // The extra collateral asset is to be sent to the treasury.
761
+ mkAssetsOf(collateralAssetA, LIQUIDATED_COLLATERAL + 1_000_000n),
761
762
  context.lucid,
762
763
  );
763
764
 
@@ -1130,7 +1131,8 @@ describe('Stability pool', () => {
1130
1131
  // Send funds to user4 so liquidation is performed from a clean address.
1131
1132
  await sendValueTo(
1132
1133
  context.users.user4.address,
1133
- mkAssetsOf(collateralAssetA, LIQUIDATED_COLLATERAL),
1134
+ // The extra collateral asset is to be sent to the treasury.
1135
+ mkAssetsOf(collateralAssetA, LIQUIDATED_COLLATERAL + 1_000_000n),
1134
1136
  context.lucid,
1135
1137
  );
1136
1138
 
@@ -1784,7 +1786,8 @@ describe('Stability pool', () => {
1784
1786
  // Send funds to user4 so liquidation is performed from a clean address.
1785
1787
  await sendValueTo(
1786
1788
  context.users.user4.address,
1787
- mkAssetsOf(collateralAssetA, LIQUIDATED_COLLATERAL),
1789
+ // The extra collateral asset is to be sent to the treasury.
1790
+ mkAssetsOf(collateralAssetA, LIQUIDATED_COLLATERAL + 1_000_000n),
1788
1791
  context.lucid,
1789
1792
  );
1790
1793
 
@@ -1920,8 +1923,9 @@ describe('Stability pool', () => {
1920
1923
  });
1921
1924
  });
1922
1925
 
1926
+ // These are the most significant tests for benchmarking the maximum number of collateral assets supported.
1923
1927
  describe('Liquidate', () => {
1924
- test<MyContext>('Liquidate adding 9th reward asset', async (context: MyContext) => {
1928
+ test<MyContext>('Liquidate with 10 reward assets in the pool - collecting with 2 assets in treasury', async (context: MyContext) => {
1925
1929
  context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
1926
1930
 
1927
1931
  const initialAssets = [
@@ -1934,9 +1938,12 @@ describe('Stability pool', () => {
1934
1938
  collateralAssetF,
1935
1939
  collateralAssetG,
1936
1940
  collateralAssetH,
1941
+ collateralAssetI,
1937
1942
  ];
1938
1943
 
1939
- expect(initialAssets.length, 'Unexpected reward assets count').toEqual(9);
1944
+ expect(initialAssets.length, 'Unexpected reward assets count').toEqual(
1945
+ 10,
1946
+ );
1940
1947
 
1941
1948
  const [sysParams, [iusdAssetInfo]] = await init(
1942
1949
  context.lucid,
@@ -1991,7 +1998,204 @@ describe('Stability pool', () => {
1991
1998
  context.lucid,
1992
1999
  requestSpAccountCreation(
1993
2000
  iusdAssetInfo.iassetTokenNameAscii,
1994
- BigInt(initialAssets.length + 1) * LIQUIDATED_DEBT,
2001
+ BigInt(initialAssets.length + 2) * LIQUIDATED_DEBT,
2002
+ sysParams,
2003
+ context.lucid,
2004
+ ),
2005
+ );
2006
+
2007
+ context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
2008
+
2009
+ await runAndAwaitTx(
2010
+ context.lucid,
2011
+ runProcessSpRequest(
2012
+ context,
2013
+ sysParams,
2014
+ iusdAssetInfo.iassetTokenNameAscii,
2015
+ paymentCredentialOf(context.users.user2.address).hash,
2016
+ ),
2017
+ );
2018
+ }
2019
+
2020
+ /**********
2021
+ * Add each collateral asset as reward to stability pool at epoch 0 and scale 0
2022
+ ***********/
2023
+ for (let idx = 0; idx < initialAssets.length; idx++) {
2024
+ const collateral = initialAssets[idx];
2025
+
2026
+ context.lucid.selectWallet.fromSeed(context.users.user3.seedPhrase);
2027
+
2028
+ // Send funds to user4 so liquidation is performed from a clean address.
2029
+ await sendValueTo(
2030
+ context.users.user4.address,
2031
+ // The extra collateral asset is to be sent to the treasury.
2032
+ mkAssetsOf(collateral, LIQUIDATED_COLLATERAL + 1_000_000n),
2033
+ context.lucid,
2034
+ );
2035
+
2036
+ context.emulator.awaitSlot(1000);
2037
+
2038
+ context.lucid.selectWallet.fromSeed(context.users.user4.seedPhrase);
2039
+
2040
+ await refreshPriceOracle(context, sysParams, iusdAssetInfo, collateral);
2041
+
2042
+ await executeLiquidation(
2043
+ context,
2044
+ sysParams,
2045
+ LIQUIDATED_DEBT,
2046
+ LIQUIDATED_COLLATERAL,
2047
+ collateral,
2048
+ iusdAssetInfo,
2049
+ );
2050
+ }
2051
+
2052
+ /**********
2053
+ * Execute last liquidation
2054
+ ***********/
2055
+
2056
+ {
2057
+ {
2058
+ const sp = await findStabilityPool(
2059
+ context.lucid,
2060
+ sysParams,
2061
+ iusdAssetInfo.iassetTokenNameAscii,
2062
+ );
2063
+
2064
+ expect(sp.datum.state.epoch, 'Unexpected epoch').toEqual(0n);
2065
+ expect(sp.datum.state.scale, 'Unexpected scale').toEqual(0n);
2066
+ expect(
2067
+ sp.datum.assetStates.length,
2068
+ 'Unexpected asset states',
2069
+ ).toEqual(initialAssets.length);
2070
+ }
2071
+
2072
+ const collateral = initialAssets[initialAssets.length - 1];
2073
+
2074
+ // Make sure that the liquidation will be performed using a treasury UTxO with 2 assets.
2075
+ assert(collateral !== adaAssetClass);
2076
+
2077
+ context.lucid.selectWallet.fromSeed(context.users.user3.seedPhrase);
2078
+
2079
+ // Send funds to user4 so liquidation is performed from a clean address.
2080
+ await sendValueTo(
2081
+ context.users.user4.address,
2082
+ // The extra collateral asset is to be sent to the treasury.
2083
+ mkAssetsOf(collateral, LIQUIDATED_COLLATERAL + 1_000_000n),
2084
+ context.lucid,
2085
+ );
2086
+
2087
+ context.emulator.awaitSlot(1000);
2088
+
2089
+ context.lucid.selectWallet.fromSeed(context.users.user4.seedPhrase);
2090
+
2091
+ await refreshPriceOracle(context, sysParams, iusdAssetInfo, collateral);
2092
+
2093
+ await executeLiquidation(
2094
+ context,
2095
+ sysParams,
2096
+ LIQUIDATED_DEBT,
2097
+ LIQUIDATED_COLLATERAL,
2098
+ collateral,
2099
+ iusdAssetInfo,
2100
+ (tx) =>
2101
+ benchmarkAndAwaitTx(
2102
+ 'Stability Pool - Liquidate with 10 reward assets in the pool - collecting with 2 assets in treasury',
2103
+ tx,
2104
+ context.lucid,
2105
+ context.emulator,
2106
+ ),
2107
+ );
2108
+ }
2109
+
2110
+ {
2111
+ const sp = await findStabilityPool(
2112
+ context.lucid,
2113
+ sysParams,
2114
+ iusdAssetInfo.iassetTokenNameAscii,
2115
+ );
2116
+
2117
+ expect(sp.datum.state.epoch, 'Unexpected epoch').toEqual(0n);
2118
+ expect(sp.datum.state.scale, 'Unexpected scale').toEqual(0n);
2119
+ expect(sp.datum.assetStates.length, 'Unexpected asset states').toEqual(
2120
+ initialAssets.length,
2121
+ );
2122
+ }
2123
+ });
2124
+
2125
+ test<MyContext>('Liquidate with 10 reward assets in the pool - direct treasury payment', async (context: MyContext) => {
2126
+ context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
2127
+
2128
+ const initialAssets = [
2129
+ adaAssetClass,
2130
+ collateralAssetA,
2131
+ collateralAssetB,
2132
+ collateralAssetC,
2133
+ collateralAssetD,
2134
+ collateralAssetE,
2135
+ collateralAssetF,
2136
+ collateralAssetG,
2137
+ collateralAssetH,
2138
+ collateralAssetI,
2139
+ ];
2140
+
2141
+ expect(initialAssets.length, 'Unexpected reward assets count').toEqual(
2142
+ 10,
2143
+ );
2144
+
2145
+ const [sysParams, [iusdAssetInfo]] = await init(
2146
+ context.lucid,
2147
+ [
2148
+ {
2149
+ ...iusdInitialAssetCfg(),
2150
+ collateralAssets: mkCollateralAssetsChain(
2151
+ initialAssets.map((a) => mkBaseCollateralAsset(a, 0n)),
2152
+ ),
2153
+ },
2154
+ ],
2155
+ context.emulator.slot,
2156
+ );
2157
+
2158
+ await createMultipleUtxosAtTreasury(
2159
+ mkLovelacesOf(2n),
2160
+ 16n,
2161
+ sysParams,
2162
+ context,
2163
+ );
2164
+
2165
+ // After price doubles the collateral ratio will be 110%
2166
+ const LIQUIDATED_DEBT = 5_000_000n;
2167
+ const LIQUIDATED_COLLATERAL = 11_000_000n;
2168
+
2169
+ /**********
2170
+ * Create account for user2
2171
+ ***********/
2172
+ {
2173
+ context.lucid.selectWallet.fromSeed(context.users.user2.seedPhrase);
2174
+
2175
+ await refreshPriceOracle(
2176
+ context,
2177
+ sysParams,
2178
+ iusdAssetInfo,
2179
+ collateralAssetA,
2180
+ );
2181
+
2182
+ await runAndAwaitTx(
2183
+ context.lucid,
2184
+ runOpenCdp(
2185
+ context,
2186
+ sysParams,
2187
+ iusdAssetInfo.iassetTokenNameAscii,
2188
+ collateralAssetA,
2189
+ 10_000_000_000n,
2190
+ 3_000_000_000n,
2191
+ ),
2192
+ );
2193
+
2194
+ await runAndAwaitTx(
2195
+ context.lucid,
2196
+ requestSpAccountCreation(
2197
+ iusdAssetInfo.iassetTokenNameAscii,
2198
+ BigInt(initialAssets.length + 2) * LIQUIDATED_DEBT,
1995
2199
  sysParams,
1996
2200
  context.lucid,
1997
2201
  ),
@@ -2013,7 +2217,7 @@ describe('Stability pool', () => {
2013
2217
  /**********
2014
2218
  * Add each collateral asset as reward to stability pool at epoch 0 and scale 0
2015
2219
  ***********/
2016
- for (let idx = 0; idx < initialAssets.length - 1; idx++) {
2220
+ for (let idx = 0; idx < initialAssets.length; idx++) {
2017
2221
  const collateral = initialAssets[idx];
2018
2222
 
2019
2223
  context.lucid.selectWallet.fromSeed(context.users.user3.seedPhrase);
@@ -2038,6 +2242,8 @@ describe('Stability pool', () => {
2038
2242
  LIQUIDATED_COLLATERAL,
2039
2243
  collateral,
2040
2244
  iusdAssetInfo,
2245
+ undefined,
2246
+ true,
2041
2247
  );
2042
2248
  }
2043
2249
 
@@ -2058,7 +2264,7 @@ describe('Stability pool', () => {
2058
2264
  expect(
2059
2265
  sp.datum.assetStates.length,
2060
2266
  'Unexpected asset states',
2061
- ).toEqual(initialAssets.length - 1);
2267
+ ).toEqual(initialAssets.length);
2062
2268
  }
2063
2269
 
2064
2270
  const collateral = initialAssets[initialAssets.length - 1];
@@ -2087,11 +2293,12 @@ describe('Stability pool', () => {
2087
2293
  iusdAssetInfo,
2088
2294
  (tx) =>
2089
2295
  benchmarkAndAwaitTx(
2090
- 'Stability Pool - Liquidate adding 9th reward asset',
2296
+ 'Stability Pool - Liquidate with 10 reward assets in the pool - direct treasury payment',
2091
2297
  tx,
2092
2298
  context.lucid,
2093
2299
  context.emulator,
2094
2300
  ),
2301
+ true,
2095
2302
  );
2096
2303
  }
2097
2304
 
@@ -2110,7 +2317,7 @@ describe('Stability pool', () => {
2110
2317
  }
2111
2318
  });
2112
2319
 
2113
- test<MyContext>('Liquidate adding 9th reward asset and increasing epoch', async (context: MyContext) => {
2320
+ test<MyContext>('Liquidate with 9 reward assets in the pool and increasing epoch', async (context: MyContext) => {
2114
2321
  context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
2115
2322
 
2116
2323
  const initialAssets = [
@@ -2180,7 +2387,7 @@ describe('Stability pool', () => {
2180
2387
  context.lucid,
2181
2388
  requestSpAccountCreation(
2182
2389
  iusdAssetInfo.iassetTokenNameAscii,
2183
- BigInt(initialAssets.length) * LIQUIDATED_DEBT,
2390
+ BigInt(initialAssets.length + 1) * LIQUIDATED_DEBT,
2184
2391
  sysParams,
2185
2392
  context.lucid,
2186
2393
  ),
@@ -2202,7 +2409,7 @@ describe('Stability pool', () => {
2202
2409
  /**********
2203
2410
  * Add each collateral asset as reward to stability pool at epoch 0 and scale 0
2204
2411
  ***********/
2205
- for (let idx = 0; idx < initialAssets.length - 1; idx++) {
2412
+ for (let idx = 0; idx < initialAssets.length; idx++) {
2206
2413
  const collateral = initialAssets[idx];
2207
2414
 
2208
2415
  context.lucid.selectWallet.fromSeed(context.users.user3.seedPhrase);
@@ -2210,7 +2417,8 @@ describe('Stability pool', () => {
2210
2417
  // Send funds to user4 so liquidation is performed from a clean address.
2211
2418
  await sendValueTo(
2212
2419
  context.users.user4.address,
2213
- mkAssetsOf(collateral, LIQUIDATED_COLLATERAL),
2420
+ // The extra collateral asset is to be sent to the treasury.
2421
+ mkAssetsOf(collateral, LIQUIDATED_COLLATERAL + 1_000_000n),
2214
2422
  context.lucid,
2215
2423
  );
2216
2424
 
@@ -2245,17 +2453,21 @@ describe('Stability pool', () => {
2245
2453
  expect(
2246
2454
  sp.datum.assetStates.length,
2247
2455
  'Unexpected asset states',
2248
- ).toEqual(initialAssets.length - 1);
2456
+ ).toEqual(initialAssets.length);
2249
2457
  }
2250
2458
 
2251
2459
  const collateral = initialAssets[initialAssets.length - 1];
2252
2460
 
2461
+ // Make sure that the liquidation will be performed using a treasury UTxO with 2 assets.
2462
+ assert(collateral !== adaAssetClass);
2463
+
2253
2464
  context.lucid.selectWallet.fromSeed(context.users.user3.seedPhrase);
2254
2465
 
2255
2466
  // Send funds to user4 so liquidation is performed from a clean address.
2256
2467
  await sendValueTo(
2257
2468
  context.users.user4.address,
2258
- mkAssetsOf(collateral, LIQUIDATED_COLLATERAL),
2469
+ // The extra collateral asset is to be sent to the treasury.
2470
+ mkAssetsOf(collateral, LIQUIDATED_COLLATERAL + 1_000_000n),
2259
2471
  context.lucid,
2260
2472
  );
2261
2473
 
@@ -2272,7 +2484,7 @@ describe('Stability pool', () => {
2272
2484
  iusdAssetInfo,
2273
2485
  async (tx) =>
2274
2486
  benchmarkAndAwaitTx(
2275
- 'Stability Pool - Liquidate adding 9th reward asset and increasing epoch',
2487
+ 'Stability Pool - Liquidate with 9 reward assets in the pool and increasing epoch',
2276
2488
  tx,
2277
2489
  context.lucid,
2278
2490
  context.emulator,
@@ -2294,7 +2506,9 @@ describe('Stability pool', () => {
2294
2506
  }
2295
2507
  });
2296
2508
 
2297
- test<MyContext>('Liquidate adding 9th reward asset and increasing scale', async (context: MyContext) => {
2509
+ // TODO: This test shows abnormally low memory and CPU use compared with the other similar tests
2510
+ // (e.g. the test above increasing epoch) or this very test performed with one less asset.
2511
+ test<MyContext>('Liquidate with 10 reward assets in the pool and increasing scale', async (context: MyContext) => {
2298
2512
  context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
2299
2513
 
2300
2514
  const initialAssets = [
@@ -2307,9 +2521,12 @@ describe('Stability pool', () => {
2307
2521
  collateralAssetF,
2308
2522
  collateralAssetG,
2309
2523
  collateralAssetH,
2524
+ collateralAssetI,
2310
2525
  ];
2311
2526
 
2312
- expect(initialAssets.length, 'Unexpected reward assets count').toEqual(9);
2527
+ expect(initialAssets.length, 'Unexpected reward assets count').toEqual(
2528
+ 10,
2529
+ );
2313
2530
 
2314
2531
  const [sysParams, [iusdAssetInfo]] = await init(
2315
2532
  context.lucid,
@@ -2364,7 +2581,7 @@ describe('Stability pool', () => {
2364
2581
  context.lucid,
2365
2582
  requestSpAccountCreation(
2366
2583
  iusdAssetInfo.iassetTokenNameAscii,
2367
- BigInt(initialAssets.length - 1) * LIQUIDATED_DEBT +
2584
+ BigInt(initialAssets.length) * LIQUIDATED_DEBT +
2368
2585
  LIQUIDATED_DEBT +
2369
2586
  10n,
2370
2587
  sysParams,
@@ -2388,7 +2605,7 @@ describe('Stability pool', () => {
2388
2605
  /**********
2389
2606
  * Add each collateral asset as reward to stability pool at epoch 0 and scale 0
2390
2607
  ***********/
2391
- for (let idx = 0; idx < initialAssets.length - 1; idx++) {
2608
+ for (let idx = 0; idx < initialAssets.length; idx++) {
2392
2609
  const collateral = initialAssets[idx];
2393
2610
 
2394
2611
  context.lucid.selectWallet.fromSeed(context.users.user3.seedPhrase);
@@ -2396,7 +2613,8 @@ describe('Stability pool', () => {
2396
2613
  // Send funds to user4 so liquidation is performed from a clean address.
2397
2614
  await sendValueTo(
2398
2615
  context.users.user4.address,
2399
- mkAssetsOf(collateral, LIQUIDATED_COLLATERAL),
2616
+ // The extra collateral asset is to be sent to the treasury.
2617
+ mkAssetsOf(collateral, LIQUIDATED_COLLATERAL + 1_000_000n),
2400
2618
  context.lucid,
2401
2619
  );
2402
2620
 
@@ -2421,6 +2639,13 @@ describe('Stability pool', () => {
2421
2639
  await repeat(1, async () => {
2422
2640
  context.lucid.selectWallet.fromSeed(context.users.user4.seedPhrase);
2423
2641
 
2642
+ await refreshPriceOracle(
2643
+ context,
2644
+ sysParams,
2645
+ iusdAssetInfo,
2646
+ adaAssetClass,
2647
+ );
2648
+
2424
2649
  await executeLiquidation(
2425
2650
  context,
2426
2651
  sysParams,
@@ -2472,7 +2697,7 @@ describe('Stability pool', () => {
2472
2697
  expect(
2473
2698
  sp.datum.assetStates.length,
2474
2699
  'Unexpected asset states',
2475
- ).toEqual(initialAssets.length - 1);
2700
+ ).toEqual(initialAssets.length);
2476
2701
  }
2477
2702
 
2478
2703
  const collateral = initialAssets[initialAssets.length - 1];
@@ -2482,7 +2707,8 @@ describe('Stability pool', () => {
2482
2707
  // Send funds to user4 so liquidation is performed from a clean address.
2483
2708
  await sendValueTo(
2484
2709
  context.users.user4.address,
2485
- mkAssetsOf(collateral, LIQUIDATED_COLLATERAL),
2710
+ // The extra collateral asset is to be sent to the treasury.
2711
+ mkAssetsOf(collateral, LIQUIDATED_COLLATERAL + 1_000_000n),
2486
2712
  context.lucid,
2487
2713
  );
2488
2714
 
@@ -2499,7 +2725,7 @@ describe('Stability pool', () => {
2499
2725
  iusdAssetInfo,
2500
2726
  (tx) =>
2501
2727
  benchmarkAndAwaitTx(
2502
- 'Stability Pool - Liquidate adding 9th reward asset and increasing scale',
2728
+ 'Stability Pool - Liquidate with 10 reward assets in the pool and increasing scale',
2503
2729
  tx,
2504
2730
  context.lucid,
2505
2731
  context.emulator,