@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,4471 +0,0 @@
1
- import { assert, beforeEach, expect, test } from 'vitest';
2
- import {
3
- IndigoTestContext,
4
- repeat,
5
- runAndAwaitTx,
6
- runAndAwaitTxBuilder,
7
- } from '../test-helpers';
8
- import {
9
- createIndigoTestContext,
10
- EXAMPLE_TOKEN_1,
11
- EXAMPLE_TOKEN_2,
12
- } from '../indigo-test-helpers';
13
- import { benchmarkAndAwaitTx } from '../utils/benchmark-utils';
14
- import {
15
- batchProcessStableswapOrders,
16
- cancelStableswapOrder,
17
- createStableswapOrder,
18
- updateStableswapPoolFees,
19
- } from '../../src/contracts/stableswap/transactions';
20
- import {
21
- createScriptAddress,
22
- fromSystemParamsAsset,
23
- mkTreasuryAddr,
24
- } from '../../src';
25
- import {
26
- addAssets,
27
- Assets,
28
- credentialToAddress,
29
- fromHex,
30
- fromText,
31
- paymentCredentialOf,
32
- UTxO,
33
- } from '@lucid-evolution/lucid';
34
- import {
35
- findAllNecessaryOrefs,
36
- findPriceOracleFromCollateralAsset,
37
- findStableswapPool,
38
- } from '../cdp/cdp-queries';
39
- import {
40
- findAllStableswapOrders,
41
- findSingleStableswapOrder,
42
- findStableswapOrders,
43
- } from './stableswap-queries';
44
- import { feedPriceOracleTx } from '../../src/contracts/price-oracle/transactions';
45
- import {
46
- adaAssetClass,
47
- addressFromBech32,
48
- assetClassValueOf,
49
- lovelacesAmt,
50
- mkLovelacesOf,
51
- negateAssets,
52
- } from '@3rd-eye-labs/cardano-offchain-common';
53
- import { runCreateStableswapPool } from './stableswap-actions';
54
- import { getValueChangeAtAddressAfterAction } from '../utils';
55
- import { array as A } from 'fp-ts';
56
- import { runOpenCdp } from '../cdp/actions';
57
- import { Data } from '@evolution-sdk/evolution';
58
- import { serialiseStableswapOrderDatum } from '../../src/contracts/stableswap/types-new';
59
- import {
60
- BASE_MAX_EXECUTION_FEE,
61
- pickValidSatisfiableOrders,
62
- } from '../../src/contracts/stableswap/helpers';
63
- import { StableswapPoolContent } from '../../src/contracts/cdp/types-new';
64
- import { mutatedBatchProcessStableswapOrders } from './transactions-mutated';
65
- import { expectScriptFailure } from '../utils/asserts';
66
- import {
67
- findRandomTreasuryUtxoWithOnlyAda,
68
- findRandomTreasuryUtxoWithAsset,
69
- } from '../../src/contracts/treasury/queries';
70
- import { createUtxoAtTreasury } from '../endpoints/treasury';
71
- import { rationalFromInt, rationalZero } from '../../src/types/rational';
72
- import { refreshPriceOracle } from '../price-oracle/actions';
73
-
74
- beforeEach<IndigoTestContext>(async (context: IndigoTestContext) => {
75
- await createIndigoTestContext(context);
76
- });
77
-
78
- test<IndigoTestContext>('Stableswap - Create Order', async (context: IndigoTestContext) => {
79
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
80
-
81
- await runCreateStableswapPool(
82
- context.assetConfigs[0].iassetTokenNameAscii,
83
- EXAMPLE_TOKEN_1,
84
- context,
85
- );
86
-
87
- const stableswapPool = await findStableswapPool(
88
- context.lucid,
89
- context.systemParams.validatorHashes.cdpHash,
90
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
91
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
92
- EXAMPLE_TOKEN_1,
93
- );
94
-
95
- context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
96
-
97
- await benchmarkAndAwaitTx(
98
- 'Stableswap - Create Order',
99
- await createStableswapOrder(
100
- context.assetConfigs[0].iassetTokenNameAscii,
101
- EXAMPLE_TOKEN_1,
102
- 10_000_000n,
103
- true,
104
- stableswapPool.datum,
105
- context.systemParams,
106
- context.lucid,
107
- ),
108
- context.lucid,
109
- context.emulator,
110
- );
111
- });
112
-
113
- test<IndigoTestContext>('Stableswap - Cancel Order', async (context: IndigoTestContext) => {
114
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
115
-
116
- await runCreateStableswapPool(
117
- context.assetConfigs[0].iassetTokenNameAscii,
118
- EXAMPLE_TOKEN_1,
119
- context,
120
- );
121
-
122
- const stableswapPool = await findStableswapPool(
123
- context.lucid,
124
- context.systemParams.validatorHashes.cdpHash,
125
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
126
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
127
- EXAMPLE_TOKEN_1,
128
- );
129
-
130
- context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
131
-
132
- await runAndAwaitTx(
133
- context.lucid,
134
- createStableswapOrder(
135
- context.assetConfigs[0].iassetTokenNameAscii,
136
- EXAMPLE_TOKEN_1,
137
- 10_000_000n,
138
- true,
139
- stableswapPool.datum,
140
- context.systemParams,
141
- context.lucid,
142
- ),
143
- );
144
-
145
- const stableswapOrder = await findSingleStableswapOrder(
146
- context.lucid,
147
- context.systemParams.validatorHashes.stableswapHash,
148
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
149
- EXAMPLE_TOKEN_1,
150
- );
151
-
152
- await benchmarkAndAwaitTx(
153
- 'Stableswap - Cancel Order',
154
- await cancelStableswapOrder(
155
- stableswapOrder.utxo,
156
- context.systemParams,
157
- context.lucid,
158
- ),
159
- context.lucid,
160
- context.emulator,
161
- );
162
- });
163
-
164
- test<IndigoTestContext>('Stableswap - Batch a single order to mint', async (context: IndigoTestContext) => {
165
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
166
-
167
- await runCreateStableswapPool(
168
- context.assetConfigs[0].iassetTokenNameAscii,
169
- EXAMPLE_TOKEN_1,
170
- context,
171
- );
172
-
173
- let stableswapPool = await findStableswapPool(
174
- context.lucid,
175
- context.systemParams.validatorHashes.cdpHash,
176
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
177
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
178
- EXAMPLE_TOKEN_1,
179
- );
180
-
181
- context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
182
-
183
- const initialUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
184
- addAssets(acc, utxo.assets),
185
- )(await context.lucid.utxosAt(context.users.user.address));
186
-
187
- await runAndAwaitTx(
188
- context.lucid,
189
- createStableswapOrder(
190
- context.assetConfigs[0].iassetTokenNameAscii,
191
- EXAMPLE_TOKEN_1,
192
- 10_000_000n,
193
- true,
194
- stableswapPool.datum,
195
- context.systemParams,
196
- context.lucid,
197
- ),
198
- );
199
-
200
- const stableswapOrder = await findSingleStableswapOrder(
201
- context.lucid,
202
- context.systemParams.validatorHashes.stableswapHash,
203
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
204
- EXAMPLE_TOKEN_1,
205
- );
206
-
207
- await createUtxoAtTreasury(
208
- mkLovelacesOf(2_000_000n),
209
- context.systemParams,
210
- context,
211
- );
212
-
213
- const treasuryUtxo = await findRandomTreasuryUtxoWithOnlyAda(
214
- context.lucid,
215
- context.systemParams,
216
- );
217
-
218
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
219
-
220
- const [__, treasuryValChange] = await getValueChangeAtAddressAfterAction(
221
- context.lucid,
222
- mkTreasuryAddr(context.lucid, context.systemParams),
223
- async () =>
224
- benchmarkAndAwaitTx(
225
- 'Stableswap - Batch a single order to mint',
226
- await batchProcessStableswapOrders(
227
- [stableswapOrder.utxo],
228
- stableswapPool.utxo,
229
- treasuryUtxo,
230
- context.systemParams,
231
- context.lucid,
232
- ),
233
- context.lucid,
234
- context.emulator,
235
- ),
236
- );
237
-
238
- ///////////////////////////////////
239
- // Checks after last transaction //
240
- ///////////////////////////////////
241
-
242
- stableswapPool = await findStableswapPool(
243
- context.lucid,
244
- context.systemParams.validatorHashes.cdpHash,
245
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
246
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
247
- EXAMPLE_TOKEN_1,
248
- );
249
-
250
- const finalUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
251
- addAssets(acc, utxo.assets),
252
- )(await context.lucid.utxosAt(context.users.user.address));
253
-
254
- const userValueDiff = addAssets(
255
- finalUserValue,
256
- negateAssets(initialUserValue),
257
- );
258
-
259
- const iassetAc = {
260
- currencySymbol: fromHex(
261
- context.systemParams.stableswapParams.iassetSymbol.unCurrencySymbol,
262
- ),
263
- tokenName: stableswapOrder.datum.iasset,
264
- };
265
-
266
- assert(
267
- assetClassValueOf(treasuryValChange, iassetAc) == 50_000n,
268
- 'Unexpected iAsset value received by the treasury',
269
- );
270
-
271
- assert(
272
- assetClassValueOf(stableswapPool.utxo.assets, EXAMPLE_TOKEN_1) ==
273
- 10_000_000n,
274
- 'Unexpected value held by stableswap pool',
275
- );
276
-
277
- assert(
278
- assetClassValueOf(userValueDiff, iassetAc) == 10_000_000n - 50_000n,
279
- 'Unexpected value received by order owner',
280
- );
281
- });
282
-
283
- test<IndigoTestContext>('Stableswap - Batch a single order to mint with no minting fee', async (context: IndigoTestContext) => {
284
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
285
-
286
- await runCreateStableswapPool(
287
- context.assetConfigs[0].iassetTokenNameAscii,
288
- EXAMPLE_TOKEN_1,
289
- context,
290
- rationalFromInt(1n),
291
- // 0% minting fee.
292
- rationalZero,
293
- );
294
-
295
- let stableswapPool = await findStableswapPool(
296
- context.lucid,
297
- context.systemParams.validatorHashes.cdpHash,
298
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
299
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
300
- EXAMPLE_TOKEN_1,
301
- );
302
-
303
- context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
304
-
305
- const initialUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
306
- addAssets(acc, utxo.assets),
307
- )(await context.lucid.utxosAt(context.users.user.address));
308
-
309
- await runAndAwaitTx(
310
- context.lucid,
311
- createStableswapOrder(
312
- context.assetConfigs[0].iassetTokenNameAscii,
313
- EXAMPLE_TOKEN_1,
314
- 10_000_000n,
315
- true,
316
- stableswapPool.datum,
317
- context.systemParams,
318
- context.lucid,
319
- ),
320
- );
321
-
322
- const stableswapOrder = await findSingleStableswapOrder(
323
- context.lucid,
324
- context.systemParams.validatorHashes.stableswapHash,
325
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
326
- EXAMPLE_TOKEN_1,
327
- );
328
-
329
- await createUtxoAtTreasury(
330
- mkLovelacesOf(2_000_000n),
331
- context.systemParams,
332
- context,
333
- );
334
-
335
- const treasuryUtxo = await findRandomTreasuryUtxoWithOnlyAda(
336
- context.lucid,
337
- context.systemParams,
338
- );
339
-
340
- const [__, treasuryValChange] = await getValueChangeAtAddressAfterAction(
341
- context.lucid,
342
- mkTreasuryAddr(context.lucid, context.systemParams),
343
- async () =>
344
- await runAndAwaitTx(
345
- context.lucid,
346
- batchProcessStableswapOrders(
347
- [stableswapOrder.utxo],
348
- stableswapPool.utxo,
349
- treasuryUtxo,
350
- context.systemParams,
351
- context.lucid,
352
- ),
353
- ),
354
- );
355
-
356
- ///////////////////////////////////
357
- // Checks after last transaction //
358
- ///////////////////////////////////
359
-
360
- stableswapPool = await findStableswapPool(
361
- context.lucid,
362
- context.systemParams.validatorHashes.cdpHash,
363
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
364
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
365
- EXAMPLE_TOKEN_1,
366
- );
367
-
368
- const finalUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
369
- addAssets(acc, utxo.assets),
370
- )(await context.lucid.utxosAt(context.users.user.address));
371
-
372
- const userValueDiff = addAssets(
373
- finalUserValue,
374
- negateAssets(initialUserValue),
375
- );
376
-
377
- const iassetAc = {
378
- currencySymbol: fromHex(
379
- context.systemParams.stableswapParams.iassetSymbol.unCurrencySymbol,
380
- ),
381
- tokenName: stableswapOrder.datum.iasset,
382
- };
383
-
384
- assert(
385
- assetClassValueOf(treasuryValChange, iassetAc) == 0n,
386
- 'Unexpected iAsset value received by the treasury',
387
- );
388
-
389
- assert(
390
- assetClassValueOf(stableswapPool.utxo.assets, EXAMPLE_TOKEN_1) ==
391
- 10_000_000n,
392
- 'Unexpected value held by stableswap pool',
393
- );
394
-
395
- assert(
396
- assetClassValueOf(userValueDiff, iassetAc) == 10_000_000n,
397
- 'Unexpected value received by order owner',
398
- );
399
- });
400
-
401
- test<IndigoTestContext>('Stableswap - pickValidSatisfiableOrders', async (context: IndigoTestContext) => {
402
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
403
-
404
- await runCreateStableswapPool(
405
- context.assetConfigs[0].iassetTokenNameAscii,
406
- EXAMPLE_TOKEN_1,
407
- context,
408
- rationalFromInt(1n),
409
- { numerator: 5n, denominator: 1000n },
410
- { numerator: 5n, denominator: 1000n },
411
- );
412
-
413
- const stableswapPool = await findStableswapPool(
414
- context.lucid,
415
- context.systemParams.validatorHashes.cdpHash,
416
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
417
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
418
- EXAMPLE_TOKEN_1,
419
- );
420
-
421
- await refreshPriceOracle(
422
- context,
423
- context.systemParams,
424
- context.assetConfigs[0],
425
- adaAssetClass,
426
- );
427
- await refreshPriceOracle(
428
- context,
429
- context.systemParams,
430
- context.assetConfigs[1],
431
- adaAssetClass,
432
- );
433
-
434
- context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
435
-
436
- // Add some IUSD to wallet
437
- await runAndAwaitTx(
438
- context.lucid,
439
- runOpenCdp(
440
- context,
441
- context.systemParams,
442
- context.assetConfigs[0].iassetTokenNameAscii,
443
- adaAssetClass,
444
- 100_000_000n,
445
- 50_000_000n,
446
- ),
447
- );
448
-
449
- // iEUR
450
- await runAndAwaitTx(
451
- context.lucid,
452
- runOpenCdp(
453
- context,
454
- context.systemParams,
455
- context.assetConfigs[1].iassetTokenNameAscii,
456
- adaAssetClass,
457
- 100_000_000n,
458
- 50_000_000n,
459
- ),
460
- );
461
-
462
- // mint order
463
- await runAndAwaitTx(
464
- context.lucid,
465
- createStableswapOrder(
466
- context.assetConfigs[0].iassetTokenNameAscii,
467
- EXAMPLE_TOKEN_1,
468
- 10_000_000n,
469
- true,
470
- stableswapPool.datum,
471
- context.systemParams,
472
- context.lucid,
473
- ),
474
- );
475
-
476
- // mint order, can't process because not enough lovelaces
477
- const mintOrderMinLovelacesTx = await runAndAwaitTx(
478
- context.lucid,
479
- createStableswapOrder(
480
- context.assetConfigs[0].iassetTokenNameAscii,
481
- EXAMPLE_TOKEN_1,
482
- 10_000_000n,
483
- true,
484
- stableswapPool.datum,
485
- context.systemParams,
486
- context.lucid,
487
- await context.lucid.wallet().address(),
488
- undefined,
489
- BASE_MAX_EXECUTION_FEE,
490
- -200_000n,
491
- ),
492
- );
493
-
494
- const mintOtherCollateralTx = await runAndAwaitTx(
495
- context.lucid,
496
- createStableswapOrder(
497
- context.assetConfigs[0].iassetTokenNameAscii,
498
- EXAMPLE_TOKEN_2,
499
- 1_000_000n,
500
- true,
501
- stableswapPool.datum,
502
- context.systemParams,
503
- context.lucid,
504
- ),
505
- );
506
-
507
- const mintOtherIassetTx = await runAndAwaitTx(
508
- context.lucid,
509
- createStableswapOrder(
510
- 'IBTC',
511
- EXAMPLE_TOKEN_1,
512
- 1_000_000n,
513
- true,
514
- stableswapPool.datum,
515
- context.systemParams,
516
- context.lucid,
517
- ),
518
- );
519
-
520
- // mint order, can't process because max exec fee is low
521
- const mintOrderMaxExecFeeTx = await runAndAwaitTx(
522
- context.lucid,
523
- createStableswapOrder(
524
- context.assetConfigs[0].iassetTokenNameAscii,
525
- EXAMPLE_TOKEN_1,
526
- 3_000_000n,
527
- true,
528
- stableswapPool.datum,
529
- context.systemParams,
530
- context.lucid,
531
- await context.lucid.wallet().address(),
532
- undefined,
533
- 1n,
534
- ),
535
- );
536
-
537
- // mint order, this one shouldn't be processed because of maxFeeRatio
538
- const mintOrderMaxFeeTx = await runAndAwaitTx(
539
- context.lucid,
540
- createStableswapOrder(
541
- context.assetConfigs[0].iassetTokenNameAscii,
542
- EXAMPLE_TOKEN_1,
543
- 10_000_000n,
544
- true,
545
- stableswapPool.datum,
546
- context.systemParams,
547
- context.lucid,
548
- await context.lucid.wallet().address(),
549
- undefined,
550
- BASE_MAX_EXECUTION_FEE,
551
- 0n,
552
- rationalZero,
553
- ),
554
- );
555
-
556
- // Redemption order, this can't be processed because of lack of liquidity
557
- const redeemOrderTx0 = await runAndAwaitTx(
558
- context.lucid,
559
- createStableswapOrder(
560
- context.assetConfigs[0].iassetTokenNameAscii,
561
- EXAMPLE_TOKEN_1,
562
- 20_000_000n,
563
- false,
564
- stableswapPool.datum,
565
- context.systemParams,
566
- context.lucid,
567
- ),
568
- );
569
-
570
- // Redemption order
571
- await runAndAwaitTx(
572
- context.lucid,
573
- createStableswapOrder(
574
- context.assetConfigs[0].iassetTokenNameAscii,
575
- EXAMPLE_TOKEN_1,
576
- 5_000_000n,
577
- false,
578
- stableswapPool.datum,
579
- context.systemParams,
580
- context.lucid,
581
- ),
582
- );
583
-
584
- // Redemption order
585
- const redeemOtherCollateralTx = await runAndAwaitTx(
586
- context.lucid,
587
- createStableswapOrder(
588
- context.assetConfigs[0].iassetTokenNameAscii,
589
- EXAMPLE_TOKEN_2,
590
- 1_000_000n,
591
- false,
592
- stableswapPool.datum,
593
- context.systemParams,
594
- context.lucid,
595
- ),
596
- );
597
-
598
- const redeemOtherIassetTx = await runAndAwaitTx(
599
- context.lucid,
600
- createStableswapOrder(
601
- context.assetConfigs[1].iassetTokenNameAscii,
602
- EXAMPLE_TOKEN_1,
603
- 1_000_000n,
604
- false,
605
- stableswapPool.datum,
606
- context.systemParams,
607
- context.lucid,
608
- ),
609
- );
610
-
611
- // Redemption order, can't be satisfied because of maxFeeRatio
612
- const redeemOrderMaxFeeTx = await runAndAwaitTx(
613
- context.lucid,
614
- createStableswapOrder(
615
- context.assetConfigs[0].iassetTokenNameAscii,
616
- EXAMPLE_TOKEN_1,
617
- 1_000_000n,
618
- false,
619
- stableswapPool.datum,
620
- context.systemParams,
621
- context.lucid,
622
- await context.lucid.wallet().address(),
623
- undefined,
624
- BASE_MAX_EXECUTION_FEE,
625
- 0n,
626
- rationalZero,
627
- ),
628
- );
629
-
630
- // redemption order, can't process because max exec fee is low
631
- const redemptionOrderMaxExecFeeTx = await runAndAwaitTx(
632
- context.lucid,
633
- createStableswapOrder(
634
- context.assetConfigs[0].iassetTokenNameAscii,
635
- EXAMPLE_TOKEN_1,
636
- 1_000_000n,
637
- false,
638
- stableswapPool.datum,
639
- context.systemParams,
640
- context.lucid,
641
- await context.lucid.wallet().address(),
642
- undefined,
643
- 1n,
644
- ),
645
- );
646
-
647
- // redemption order, can't process because not enough lovelaces
648
- const redemptionOrderMinLovelacesTx = await runAndAwaitTx(
649
- context.lucid,
650
- createStableswapOrder(
651
- context.assetConfigs[0].iassetTokenNameAscii,
652
- EXAMPLE_TOKEN_1,
653
- 5_000_000n,
654
- false,
655
- stableswapPool.datum,
656
- context.systemParams,
657
- context.lucid,
658
- await context.lucid.wallet().address(),
659
- undefined,
660
- BASE_MAX_EXECUTION_FEE,
661
- -500_000n,
662
- ),
663
- );
664
-
665
- const stableswapOrders = await findAllStableswapOrders(
666
- context.lucid,
667
- context.systemParams.validatorHashes.stableswapHash,
668
- );
669
-
670
- await createUtxoAtTreasury(
671
- mkLovelacesOf(2_000_000n),
672
- context.systemParams,
673
- context,
674
- );
675
-
676
- const treasuryUtxo = await findRandomTreasuryUtxoWithOnlyAda(
677
- context.lucid,
678
- context.systemParams,
679
- );
680
-
681
- const satisfiableOrders = pickValidSatisfiableOrders(
682
- context.lucid,
683
- stableswapOrders,
684
- stableswapPool,
685
- context.systemParams,
686
- );
687
-
688
- expect(satisfiableOrders.length, 'Only 2 orders are satisfiable').toEqual(2);
689
-
690
- await runAndAwaitTx(
691
- context.lucid,
692
- batchProcessStableswapOrders(
693
- satisfiableOrders.map((o) => o.utxo),
694
- stableswapPool.utxo,
695
- treasuryUtxo,
696
- context.systemParams,
697
- context.lucid,
698
- ),
699
- );
700
-
701
- ///////////////////////////////////
702
- // Checks after last transaction //
703
- ///////////////////////////////////
704
-
705
- const remainingOrders = await findAllStableswapOrders(
706
- context.lucid,
707
- context.systemParams.validatorHashes.stableswapHash,
708
- );
709
-
710
- expect(
711
- remainingOrders.map((o) => o.utxo.txHash),
712
- 'Expected different orders to not be processed',
713
- ).toEqual(
714
- expect.arrayContaining([
715
- mintOtherIassetTx,
716
- mintOtherCollateralTx,
717
- redeemOtherIassetTx,
718
- redeemOtherCollateralTx,
719
- redeemOrderMaxFeeTx,
720
- redeemOrderTx0,
721
- mintOrderMaxFeeTx,
722
- mintOrderMaxExecFeeTx,
723
- redemptionOrderMaxExecFeeTx,
724
- redemptionOrderMinLovelacesTx,
725
- mintOrderMinLovelacesTx,
726
- ]),
727
- );
728
- });
729
-
730
- test<IndigoTestContext>('Stableswap - Batch a single order to mint with collateral asset in the pool', async (context: IndigoTestContext) => {
731
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
732
-
733
- await runCreateStableswapPool(
734
- context.assetConfigs[0].iassetTokenNameAscii,
735
- EXAMPLE_TOKEN_1,
736
- context,
737
- );
738
-
739
- let stableswapPool = await findStableswapPool(
740
- context.lucid,
741
- context.systemParams.validatorHashes.cdpHash,
742
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
743
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
744
- EXAMPLE_TOKEN_1,
745
- );
746
-
747
- context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
748
-
749
- await runAndAwaitTx(
750
- context.lucid,
751
- createStableswapOrder(
752
- context.assetConfigs[0].iassetTokenNameAscii,
753
- EXAMPLE_TOKEN_1,
754
- 10_000_000n,
755
- true,
756
- stableswapPool.datum,
757
- context.systemParams,
758
- context.lucid,
759
- ),
760
- );
761
-
762
- let stableswapOrder = await findSingleStableswapOrder(
763
- context.lucid,
764
- context.systemParams.validatorHashes.stableswapHash,
765
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
766
- EXAMPLE_TOKEN_1,
767
- );
768
-
769
- await createUtxoAtTreasury(
770
- mkLovelacesOf(2_000_000n),
771
- context.systemParams,
772
- context,
773
- );
774
-
775
- let treasuryUtxo = await findRandomTreasuryUtxoWithOnlyAda(
776
- context.lucid,
777
- context.systemParams,
778
- );
779
-
780
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
781
-
782
- await runAndAwaitTx(
783
- context.lucid,
784
- batchProcessStableswapOrders(
785
- [stableswapOrder.utxo],
786
- stableswapPool.utxo,
787
- treasuryUtxo,
788
- context.systemParams,
789
- context.lucid,
790
- ),
791
- );
792
-
793
- context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
794
-
795
- const initialUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
796
- addAssets(acc, utxo.assets),
797
- )(await context.lucid.utxosAt(context.users.user.address));
798
-
799
- await runAndAwaitTx(
800
- context.lucid,
801
- createStableswapOrder(
802
- context.assetConfigs[0].iassetTokenNameAscii,
803
- EXAMPLE_TOKEN_1,
804
- 10_000_000n,
805
- true,
806
- stableswapPool.datum,
807
- context.systemParams,
808
- context.lucid,
809
- ),
810
- );
811
-
812
- stableswapOrder = await findSingleStableswapOrder(
813
- context.lucid,
814
- context.systemParams.validatorHashes.stableswapHash,
815
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
816
- EXAMPLE_TOKEN_1,
817
- );
818
-
819
- const iassetAc = {
820
- currencySymbol: fromHex(
821
- context.systemParams.stableswapParams.iassetSymbol.unCurrencySymbol,
822
- ),
823
- tokenName: stableswapOrder.datum.iasset,
824
- };
825
-
826
- treasuryUtxo = await findRandomTreasuryUtxoWithAsset(
827
- context.lucid,
828
- context.systemParams,
829
- iassetAc,
830
- );
831
-
832
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
833
-
834
- const initialAdminValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
835
- addAssets(acc, utxo.assets),
836
- )(await context.lucid.utxosAt(context.users.admin.address));
837
-
838
- stableswapPool = await findStableswapPool(
839
- context.lucid,
840
- context.systemParams.validatorHashes.cdpHash,
841
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
842
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
843
- EXAMPLE_TOKEN_1,
844
- );
845
-
846
- const [__, treasuryValChange] = await getValueChangeAtAddressAfterAction(
847
- context.lucid,
848
- mkTreasuryAddr(context.lucid, context.systemParams),
849
- async () =>
850
- benchmarkAndAwaitTx(
851
- 'Stableswap - Batch a single order to mint with collateral in the pool',
852
- await batchProcessStableswapOrders(
853
- [stableswapOrder.utxo],
854
- stableswapPool.utxo,
855
- treasuryUtxo,
856
- context.systemParams,
857
- context.lucid,
858
- ),
859
- context.lucid,
860
- context.emulator,
861
- ),
862
- );
863
-
864
- ///////////////////////////////////
865
- // Checks after last transaction //
866
- ///////////////////////////////////
867
-
868
- stableswapPool = await findStableswapPool(
869
- context.lucid,
870
- context.systemParams.validatorHashes.cdpHash,
871
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
872
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
873
- EXAMPLE_TOKEN_1,
874
- );
875
-
876
- const finalUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
877
- addAssets(acc, utxo.assets),
878
- )(await context.lucid.utxosAt(context.users.user.address));
879
-
880
- const userValueDiff = addAssets(
881
- finalUserValue,
882
- negateAssets(initialUserValue),
883
- );
884
-
885
- const finalAdminValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
886
- addAssets(acc, utxo.assets),
887
- )(await context.lucid.utxosAt(context.users.admin.address));
888
-
889
- const adminValueDiff = addAssets(
890
- finalAdminValue,
891
- negateAssets(initialAdminValue),
892
- );
893
-
894
- assert(
895
- lovelacesAmt(adminValueDiff) >= 0n &&
896
- lovelacesAmt(adminValueDiff) < 100_000n,
897
- );
898
-
899
- assert(
900
- assetClassValueOf(treasuryValChange, iassetAc) == 50_000n,
901
- 'Unexpected iAsset value received by the treasury',
902
- );
903
-
904
- assert(
905
- assetClassValueOf(stableswapPool.utxo.assets, EXAMPLE_TOKEN_1) ==
906
- 20_000_000n,
907
- 'Unexpected value held by stableswap pool',
908
- );
909
-
910
- assert(
911
- assetClassValueOf(userValueDiff, iassetAc) == 10_000_000n - 50_000n,
912
- 'Unexpected value received by order owner',
913
- );
914
- });
915
-
916
- test<IndigoTestContext>('Stableswap - Batch a single order to redeem', async (context: IndigoTestContext) => {
917
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
918
-
919
- await runCreateStableswapPool(
920
- context.assetConfigs[0].iassetTokenNameAscii,
921
- EXAMPLE_TOKEN_1,
922
- context,
923
- );
924
-
925
- let stableswapPool = await findStableswapPool(
926
- context.lucid,
927
- context.systemParams.validatorHashes.cdpHash,
928
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
929
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
930
- EXAMPLE_TOKEN_1,
931
- );
932
-
933
- context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
934
-
935
- const initialUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
936
- addAssets(acc, utxo.assets),
937
- )(await context.lucid.utxosAt(context.users.user.address));
938
-
939
- // Mint iAsset to supply the pool with collateral asset.
940
- // It also provides the treasury with a UTxO with iAsset.
941
- await runAndAwaitTx(
942
- context.lucid,
943
- createStableswapOrder(
944
- context.assetConfigs[0].iassetTokenNameAscii,
945
- EXAMPLE_TOKEN_1,
946
- 10_000_000n,
947
- true,
948
- stableswapPool.datum,
949
- context.systemParams,
950
- context.lucid,
951
- ),
952
- );
953
-
954
- let stableswapOrder = await findSingleStableswapOrder(
955
- context.lucid,
956
- context.systemParams.validatorHashes.stableswapHash,
957
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
958
- EXAMPLE_TOKEN_1,
959
- );
960
-
961
- await createUtxoAtTreasury(
962
- mkLovelacesOf(2_000_000n),
963
- context.systemParams,
964
- context,
965
- );
966
-
967
- let treasuryUtxo = await findRandomTreasuryUtxoWithOnlyAda(
968
- context.lucid,
969
- context.systemParams,
970
- );
971
-
972
- await runAndAwaitTx(
973
- context.lucid,
974
- batchProcessStableswapOrders(
975
- [stableswapOrder.utxo],
976
- stableswapPool.utxo,
977
- treasuryUtxo,
978
- context.systemParams,
979
- context.lucid,
980
- ),
981
- );
982
-
983
- // Redeem part of the collateral asset previously supplied to the pool.
984
- await runAndAwaitTx(
985
- context.lucid,
986
- createStableswapOrder(
987
- context.assetConfigs[0].iassetTokenNameAscii,
988
- EXAMPLE_TOKEN_1,
989
- 5_000_000n,
990
- false,
991
- stableswapPool.datum,
992
- context.systemParams,
993
- context.lucid,
994
- ),
995
- );
996
-
997
- stableswapOrder = await findSingleStableswapOrder(
998
- context.lucid,
999
- context.systemParams.validatorHashes.stableswapHash,
1000
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
1001
- EXAMPLE_TOKEN_1,
1002
- );
1003
-
1004
- stableswapPool = await findStableswapPool(
1005
- context.lucid,
1006
- context.systemParams.validatorHashes.cdpHash,
1007
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
1008
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
1009
- EXAMPLE_TOKEN_1,
1010
- );
1011
-
1012
- const iassetAc = {
1013
- currencySymbol: fromHex(
1014
- context.systemParams.stableswapParams.iassetSymbol.unCurrencySymbol,
1015
- ),
1016
- tokenName: stableswapOrder.datum.iasset,
1017
- };
1018
-
1019
- treasuryUtxo = await findRandomTreasuryUtxoWithAsset(
1020
- context.lucid,
1021
- context.systemParams,
1022
- iassetAc,
1023
- );
1024
-
1025
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
1026
-
1027
- const initialAdminValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
1028
- addAssets(acc, utxo.assets),
1029
- )(await context.lucid.utxosAt(context.users.admin.address));
1030
-
1031
- const [__, treasuryValChange] = await getValueChangeAtAddressAfterAction(
1032
- context.lucid,
1033
- mkTreasuryAddr(context.lucid, context.systemParams),
1034
- async () =>
1035
- benchmarkAndAwaitTx(
1036
- 'Stableswap - Batch a single order to redeem',
1037
- await batchProcessStableswapOrders(
1038
- [stableswapOrder.utxo],
1039
- stableswapPool.utxo,
1040
- treasuryUtxo,
1041
- context.systemParams,
1042
- context.lucid,
1043
- ),
1044
- context.lucid,
1045
- context.emulator,
1046
- ),
1047
- );
1048
-
1049
- ///////////////////////////////////
1050
- // Checks after last transaction //
1051
- ///////////////////////////////////
1052
-
1053
- stableswapPool = await findStableswapPool(
1054
- context.lucid,
1055
- context.systemParams.validatorHashes.cdpHash,
1056
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
1057
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
1058
- EXAMPLE_TOKEN_1,
1059
- );
1060
-
1061
- const finalUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
1062
- addAssets(acc, utxo.assets),
1063
- )(await context.lucid.utxosAt(context.users.user.address));
1064
-
1065
- const userValueDiff = addAssets(
1066
- finalUserValue,
1067
- negateAssets(initialUserValue),
1068
- );
1069
-
1070
- const finalAdminValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
1071
- addAssets(acc, utxo.assets),
1072
- )(await context.lucid.utxosAt(context.users.admin.address));
1073
-
1074
- const adminValueDiff = addAssets(
1075
- finalAdminValue,
1076
- negateAssets(initialAdminValue),
1077
- );
1078
-
1079
- assert(
1080
- lovelacesAmt(adminValueDiff) >= 0n &&
1081
- lovelacesAmt(adminValueDiff) < 100_000n,
1082
- );
1083
-
1084
- assert(
1085
- assetClassValueOf(treasuryValChange, iassetAc) == 25_000n &&
1086
- 0n <= lovelacesAmt(treasuryValChange) &&
1087
- lovelacesAmt(treasuryValChange) <= 9_000n,
1088
- 'Unexpected value received by the treasury',
1089
- );
1090
-
1091
- assert(
1092
- assetClassValueOf(stableswapPool.utxo.assets, EXAMPLE_TOKEN_1) ==
1093
- 10_000_000n - (5_000_000n - 25_000n),
1094
- 'Unexpected value held by stableswap pool',
1095
- );
1096
-
1097
- assert(
1098
- assetClassValueOf(userValueDiff, iassetAc) ==
1099
- 10_000_000n - 50_000n - 5_000_000n &&
1100
- assetClassValueOf(userValueDiff, EXAMPLE_TOKEN_1) ==
1101
- -10_000_000n + (5_000_000n - 25_000n),
1102
- 'Unexpected value received by order owner',
1103
- );
1104
- });
1105
-
1106
- test<IndigoTestContext>('Stableswap - Batch a single order to redeem with no redemption fee', async (context: IndigoTestContext) => {
1107
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
1108
-
1109
- await runCreateStableswapPool(
1110
- context.assetConfigs[0].iassetTokenNameAscii,
1111
- EXAMPLE_TOKEN_1,
1112
- context,
1113
- rationalFromInt(1n),
1114
- // 0% minting fee.
1115
- rationalZero,
1116
- // 0% redemption fee.
1117
- rationalZero,
1118
- );
1119
-
1120
- let stableswapPool = await findStableswapPool(
1121
- context.lucid,
1122
- context.systemParams.validatorHashes.cdpHash,
1123
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
1124
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
1125
- EXAMPLE_TOKEN_1,
1126
- );
1127
-
1128
- context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
1129
-
1130
- const initialUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
1131
- addAssets(acc, utxo.assets),
1132
- )(await context.lucid.utxosAt(context.users.user.address));
1133
-
1134
- // Mint iAsset to supply the pool with collateral asset.
1135
- await runAndAwaitTx(
1136
- context.lucid,
1137
- createStableswapOrder(
1138
- context.assetConfigs[0].iassetTokenNameAscii,
1139
- EXAMPLE_TOKEN_1,
1140
- 10_000_000n,
1141
- true,
1142
- stableswapPool.datum,
1143
- context.systemParams,
1144
- context.lucid,
1145
- ),
1146
- );
1147
-
1148
- let stableswapOrder = await findSingleStableswapOrder(
1149
- context.lucid,
1150
- context.systemParams.validatorHashes.stableswapHash,
1151
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
1152
- EXAMPLE_TOKEN_1,
1153
- );
1154
-
1155
- await createUtxoAtTreasury(
1156
- mkLovelacesOf(2_000_000n),
1157
- context.systemParams,
1158
- context,
1159
- );
1160
-
1161
- let treasuryUtxo = await findRandomTreasuryUtxoWithOnlyAda(
1162
- context.lucid,
1163
- context.systemParams,
1164
- );
1165
-
1166
- await runAndAwaitTx(
1167
- context.lucid,
1168
- batchProcessStableswapOrders(
1169
- [stableswapOrder.utxo],
1170
- stableswapPool.utxo,
1171
- treasuryUtxo,
1172
- context.systemParams,
1173
- context.lucid,
1174
- ),
1175
- );
1176
-
1177
- // Redeem part of the collateral asset previously supplied to the pool.
1178
- await runAndAwaitTx(
1179
- context.lucid,
1180
- createStableswapOrder(
1181
- context.assetConfigs[0].iassetTokenNameAscii,
1182
- EXAMPLE_TOKEN_1,
1183
- 5_000_000n,
1184
- false,
1185
- stableswapPool.datum,
1186
- context.systemParams,
1187
- context.lucid,
1188
- ),
1189
- );
1190
-
1191
- stableswapOrder = await findSingleStableswapOrder(
1192
- context.lucid,
1193
- context.systemParams.validatorHashes.stableswapHash,
1194
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
1195
- EXAMPLE_TOKEN_1,
1196
- );
1197
-
1198
- stableswapPool = await findStableswapPool(
1199
- context.lucid,
1200
- context.systemParams.validatorHashes.cdpHash,
1201
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
1202
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
1203
- EXAMPLE_TOKEN_1,
1204
- );
1205
-
1206
- const iassetAc = {
1207
- currencySymbol: fromHex(
1208
- context.systemParams.stableswapParams.iassetSymbol.unCurrencySymbol,
1209
- ),
1210
- tokenName: stableswapOrder.datum.iasset,
1211
- };
1212
-
1213
- // This will not be used in the transaction, but is passed only as a placeholder.
1214
- treasuryUtxo = await findRandomTreasuryUtxoWithOnlyAda(
1215
- context.lucid,
1216
- context.systemParams,
1217
- );
1218
-
1219
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
1220
-
1221
- const initialAdminValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
1222
- addAssets(acc, utxo.assets),
1223
- )(await context.lucid.utxosAt(context.users.admin.address));
1224
-
1225
- const [__, treasuryValChange] = await getValueChangeAtAddressAfterAction(
1226
- context.lucid,
1227
- mkTreasuryAddr(context.lucid, context.systemParams),
1228
- async () =>
1229
- runAndAwaitTx(
1230
- context.lucid,
1231
- batchProcessStableswapOrders(
1232
- [stableswapOrder.utxo],
1233
- stableswapPool.utxo,
1234
- treasuryUtxo,
1235
- context.systemParams,
1236
- context.lucid,
1237
- ),
1238
- ),
1239
- );
1240
-
1241
- ///////////////////////////////////
1242
- // Checks after last transaction //
1243
- ///////////////////////////////////
1244
-
1245
- stableswapPool = await findStableswapPool(
1246
- context.lucid,
1247
- context.systemParams.validatorHashes.cdpHash,
1248
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
1249
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
1250
- EXAMPLE_TOKEN_1,
1251
- );
1252
-
1253
- const finalUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
1254
- addAssets(acc, utxo.assets),
1255
- )(await context.lucid.utxosAt(context.users.user.address));
1256
-
1257
- const userValueDiff = addAssets(
1258
- finalUserValue,
1259
- negateAssets(initialUserValue),
1260
- );
1261
-
1262
- const finalAdminValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
1263
- addAssets(acc, utxo.assets),
1264
- )(await context.lucid.utxosAt(context.users.admin.address));
1265
-
1266
- const adminValueDiff = addAssets(
1267
- finalAdminValue,
1268
- negateAssets(initialAdminValue),
1269
- );
1270
-
1271
- // This one will result in a bigger gain for the admin as the tx fee is lower
1272
- assert(lovelacesAmt(adminValueDiff) >= 0n);
1273
-
1274
- assert(
1275
- assetClassValueOf(treasuryValChange, iassetAc) == 0n,
1276
- 'Unexpected value received by the treasury',
1277
- );
1278
-
1279
- assert(
1280
- assetClassValueOf(stableswapPool.utxo.assets, EXAMPLE_TOKEN_1) ==
1281
- 10_000_000n - 5_000_000n,
1282
- 'Unexpected value held by stableswap pool',
1283
- );
1284
-
1285
- assert(
1286
- assetClassValueOf(userValueDiff, iassetAc) == 10_000_000n - 5_000_000n &&
1287
- assetClassValueOf(userValueDiff, EXAMPLE_TOKEN_1) ==
1288
- -10_000_000n + 5_000_000n,
1289
- 'Unexpected value received by order owner',
1290
- );
1291
- });
1292
-
1293
- test<IndigoTestContext>('Stableswap - Batch a single order to redeem emptying the pool', async (context: IndigoTestContext) => {
1294
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
1295
-
1296
- await runCreateStableswapPool(
1297
- context.assetConfigs[0].iassetTokenNameAscii,
1298
- EXAMPLE_TOKEN_1,
1299
- context,
1300
- );
1301
-
1302
- let stableswapPool = await findStableswapPool(
1303
- context.lucid,
1304
- context.systemParams.validatorHashes.cdpHash,
1305
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
1306
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
1307
- EXAMPLE_TOKEN_1,
1308
- );
1309
-
1310
- const orefs = await findAllNecessaryOrefs(
1311
- context.lucid,
1312
- context.systemParams,
1313
- context.assetConfigs[0].iassetTokenNameAscii,
1314
- context.assetConfigs[0].collateralAssets[0].collateralAsset,
1315
- );
1316
- const priceOracleUtxo = await findPriceOracleFromCollateralAsset(
1317
- context.lucid,
1318
- orefs.collateralAsset,
1319
- );
1320
-
1321
- await runAndAwaitTx(
1322
- context.lucid,
1323
- feedPriceOracleTx(
1324
- context.lucid,
1325
- priceOracleUtxo!,
1326
- rationalFromInt(1n),
1327
- context.assetConfigs[0].collateralAssets[0].oracleParams!,
1328
- ),
1329
- );
1330
-
1331
- context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
1332
-
1333
- // Mint extra iAsset to have enough to empty the pool.
1334
- await runAndAwaitTx(
1335
- context.lucid,
1336
- runOpenCdp(
1337
- context,
1338
- context.systemParams,
1339
- context.assetConfigs[0].iassetTokenNameAscii,
1340
- context.assetConfigs[0].collateralAssets[0].collateralAsset,
1341
- 10_000_000n,
1342
- 5_000_000n,
1343
- ),
1344
- );
1345
-
1346
- const initialUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
1347
- addAssets(acc, utxo.assets),
1348
- )(await context.lucid.utxosAt(context.users.user.address));
1349
-
1350
- // Mint iAsset to supply the pool with collateral asset
1351
- // It also provides the treasury with a UTxO with iAsset.
1352
- await runAndAwaitTx(
1353
- context.lucid,
1354
- createStableswapOrder(
1355
- context.assetConfigs[0].iassetTokenNameAscii,
1356
- EXAMPLE_TOKEN_1,
1357
- 10_000_000n,
1358
- true,
1359
- stableswapPool.datum,
1360
- context.systemParams,
1361
- context.lucid,
1362
- ),
1363
- );
1364
-
1365
- let stableswapOrder = await findSingleStableswapOrder(
1366
- context.lucid,
1367
- context.systemParams.validatorHashes.stableswapHash,
1368
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
1369
- EXAMPLE_TOKEN_1,
1370
- );
1371
-
1372
- await createUtxoAtTreasury(
1373
- mkLovelacesOf(2_000_000n),
1374
- context.systemParams,
1375
- context,
1376
- );
1377
-
1378
- let treasuryUtxo = await findRandomTreasuryUtxoWithOnlyAda(
1379
- context.lucid,
1380
- context.systemParams,
1381
- );
1382
-
1383
- await runAndAwaitTx(
1384
- context.lucid,
1385
- batchProcessStableswapOrders(
1386
- [stableswapOrder.utxo],
1387
- stableswapPool.utxo,
1388
- treasuryUtxo,
1389
- context.systemParams,
1390
- context.lucid,
1391
- ),
1392
- );
1393
-
1394
- // Redeem all the assets left in the pool.
1395
- await runAndAwaitTx(
1396
- context.lucid,
1397
- createStableswapOrder(
1398
- context.assetConfigs[0].iassetTokenNameAscii,
1399
- EXAMPLE_TOKEN_1,
1400
- // After taking a 0.5% fee, the effective amount is 10_000_000.
1401
- 10_050_251n,
1402
- false,
1403
- stableswapPool.datum,
1404
- context.systemParams,
1405
- context.lucid,
1406
- ),
1407
- );
1408
-
1409
- stableswapOrder = await findSingleStableswapOrder(
1410
- context.lucid,
1411
- context.systemParams.validatorHashes.stableswapHash,
1412
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
1413
- EXAMPLE_TOKEN_1,
1414
- );
1415
-
1416
- stableswapPool = await findStableswapPool(
1417
- context.lucid,
1418
- context.systemParams.validatorHashes.cdpHash,
1419
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
1420
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
1421
- EXAMPLE_TOKEN_1,
1422
- );
1423
-
1424
- const iassetAc = {
1425
- currencySymbol: fromHex(
1426
- context.systemParams.stableswapParams.iassetSymbol.unCurrencySymbol,
1427
- ),
1428
- tokenName: stableswapOrder.datum.iasset,
1429
- };
1430
-
1431
- treasuryUtxo = await findRandomTreasuryUtxoWithAsset(
1432
- context.lucid,
1433
- context.systemParams,
1434
- iassetAc,
1435
- );
1436
-
1437
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
1438
-
1439
- const initialAdminValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
1440
- addAssets(acc, utxo.assets),
1441
- )(await context.lucid.utxosAt(context.users.admin.address));
1442
-
1443
- const [__, treasuryValChange] = await getValueChangeAtAddressAfterAction(
1444
- context.lucid,
1445
- mkTreasuryAddr(context.lucid, context.systemParams),
1446
- async () =>
1447
- runAndAwaitTx(
1448
- context.lucid,
1449
- batchProcessStableswapOrders(
1450
- [stableswapOrder.utxo],
1451
- stableswapPool.utxo,
1452
- treasuryUtxo,
1453
- context.systemParams,
1454
- context.lucid,
1455
- ),
1456
- ),
1457
- );
1458
-
1459
- ///////////////////////////////////
1460
- // Checks after last transaction //
1461
- ///////////////////////////////////
1462
-
1463
- stableswapPool = await findStableswapPool(
1464
- context.lucid,
1465
- context.systemParams.validatorHashes.cdpHash,
1466
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
1467
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
1468
- EXAMPLE_TOKEN_1,
1469
- );
1470
-
1471
- const finalUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
1472
- addAssets(acc, utxo.assets),
1473
- )(await context.lucid.utxosAt(context.users.user.address));
1474
-
1475
- const userValueDiff = addAssets(
1476
- finalUserValue,
1477
- negateAssets(initialUserValue),
1478
- );
1479
-
1480
- const finalAdminValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
1481
- addAssets(acc, utxo.assets),
1482
- )(await context.lucid.utxosAt(context.users.admin.address));
1483
-
1484
- const adminValueDiff = addAssets(
1485
- finalAdminValue,
1486
- negateAssets(initialAdminValue),
1487
- );
1488
-
1489
- assert(
1490
- lovelacesAmt(adminValueDiff) >= 0n &&
1491
- lovelacesAmt(adminValueDiff) < 100_000n,
1492
- );
1493
-
1494
- assert(
1495
- assetClassValueOf(treasuryValChange, iassetAc) == 50_251n &&
1496
- 0n <= lovelacesAmt(treasuryValChange) &&
1497
- lovelacesAmt(treasuryValChange) <= 9_000n,
1498
- 'Unexpected value received by the treasury',
1499
- );
1500
-
1501
- assert(
1502
- assetClassValueOf(stableswapPool.utxo.assets, EXAMPLE_TOKEN_1) == 0n,
1503
- 'Unexpected value held by stableswap pool',
1504
- );
1505
-
1506
- assert(
1507
- assetClassValueOf(userValueDiff, iassetAc) ==
1508
- 10_000_000n - 50_000n - 10_050_251n &&
1509
- assetClassValueOf(userValueDiff, EXAMPLE_TOKEN_1) ==
1510
- -10_000_000n + 10_000_000n,
1511
- 'Unexpected value received by order owner',
1512
- );
1513
- });
1514
-
1515
- test<IndigoTestContext>('Stableswap - Batch a single order to mint assets with smaller scale', async (context: IndigoTestContext) => {
1516
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
1517
-
1518
- await runCreateStableswapPool(
1519
- context.assetConfigs[0].iassetTokenNameAscii,
1520
- EXAMPLE_TOKEN_1,
1521
- context,
1522
- rationalFromInt(1_000n),
1523
- );
1524
-
1525
- let stableswapPool = await findStableswapPool(
1526
- context.lucid,
1527
- context.systemParams.validatorHashes.cdpHash,
1528
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
1529
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
1530
- EXAMPLE_TOKEN_1,
1531
- );
1532
-
1533
- context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
1534
-
1535
- const initialUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
1536
- addAssets(acc, utxo.assets),
1537
- )(await context.lucid.utxosAt(context.users.user.address));
1538
-
1539
- await runAndAwaitTx(
1540
- context.lucid,
1541
- createStableswapOrder(
1542
- context.assetConfigs[0].iassetTokenNameAscii,
1543
- EXAMPLE_TOKEN_1,
1544
- 10_000_000n,
1545
- true,
1546
- stableswapPool.datum,
1547
- context.systemParams,
1548
- context.lucid,
1549
- ),
1550
- );
1551
-
1552
- const stableswapOrder = await findSingleStableswapOrder(
1553
- context.lucid,
1554
- context.systemParams.validatorHashes.stableswapHash,
1555
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
1556
- EXAMPLE_TOKEN_1,
1557
- );
1558
-
1559
- await createUtxoAtTreasury(
1560
- mkLovelacesOf(2_000_000n),
1561
- context.systemParams,
1562
- context,
1563
- );
1564
-
1565
- const treasuryUtxo = await findRandomTreasuryUtxoWithOnlyAda(
1566
- context.lucid,
1567
- context.systemParams,
1568
- );
1569
-
1570
- const [__, treasuryValChange] = await getValueChangeAtAddressAfterAction(
1571
- context.lucid,
1572
- mkTreasuryAddr(context.lucid, context.systemParams),
1573
- async () =>
1574
- runAndAwaitTx(
1575
- context.lucid,
1576
- batchProcessStableswapOrders(
1577
- [stableswapOrder.utxo],
1578
- stableswapPool.utxo,
1579
- treasuryUtxo,
1580
- context.systemParams,
1581
- context.lucid,
1582
- ),
1583
- ),
1584
- );
1585
-
1586
- ///////////////////////////////////
1587
- // Checks after last transaction //
1588
- ///////////////////////////////////
1589
-
1590
- stableswapPool = await findStableswapPool(
1591
- context.lucid,
1592
- context.systemParams.validatorHashes.cdpHash,
1593
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
1594
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
1595
- EXAMPLE_TOKEN_1,
1596
- );
1597
-
1598
- const finalUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
1599
- addAssets(acc, utxo.assets),
1600
- )(await context.lucid.utxosAt(context.users.user.address));
1601
-
1602
- const userValueDiff = addAssets(
1603
- finalUserValue,
1604
- negateAssets(initialUserValue),
1605
- );
1606
-
1607
- const iassetAc = {
1608
- currencySymbol: fromHex(
1609
- context.systemParams.stableswapParams.iassetSymbol.unCurrencySymbol,
1610
- ),
1611
- tokenName: stableswapOrder.datum.iasset,
1612
- };
1613
-
1614
- assert(
1615
- assetClassValueOf(treasuryValChange, iassetAc) == 50n,
1616
- 'Unexpected iAsset value received by the treasury',
1617
- );
1618
-
1619
- assert(
1620
- assetClassValueOf(stableswapPool.utxo.assets, EXAMPLE_TOKEN_1) ==
1621
- 10_000_000n,
1622
- 'Unexpected value held by stableswap pool',
1623
- );
1624
-
1625
- assert(
1626
- assetClassValueOf(userValueDiff, iassetAc) == 10_000n - 50n,
1627
- 'Unexpected value received by order owner',
1628
- );
1629
- });
1630
-
1631
- test<IndigoTestContext>('Stableswap - Batch a single order to mint assets with bigger scale', async (context: IndigoTestContext) => {
1632
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
1633
-
1634
- await runCreateStableswapPool(
1635
- context.assetConfigs[0].iassetTokenNameAscii,
1636
- EXAMPLE_TOKEN_1,
1637
- context,
1638
- { numerator: 1n, denominator: 1_000n },
1639
- );
1640
-
1641
- let stableswapPool = await findStableswapPool(
1642
- context.lucid,
1643
- context.systemParams.validatorHashes.cdpHash,
1644
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
1645
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
1646
- EXAMPLE_TOKEN_1,
1647
- );
1648
-
1649
- context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
1650
-
1651
- const initialUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
1652
- addAssets(acc, utxo.assets),
1653
- )(await context.lucid.utxosAt(context.users.user.address));
1654
-
1655
- await runAndAwaitTx(
1656
- context.lucid,
1657
- createStableswapOrder(
1658
- context.assetConfigs[0].iassetTokenNameAscii,
1659
- EXAMPLE_TOKEN_1,
1660
- 10_000_000n,
1661
- true,
1662
- stableswapPool.datum,
1663
- context.systemParams,
1664
- context.lucid,
1665
- ),
1666
- );
1667
-
1668
- const stableswapOrder = await findSingleStableswapOrder(
1669
- context.lucid,
1670
- context.systemParams.validatorHashes.stableswapHash,
1671
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
1672
- EXAMPLE_TOKEN_1,
1673
- );
1674
-
1675
- await createUtxoAtTreasury(
1676
- mkLovelacesOf(2_000_000n),
1677
- context.systemParams,
1678
- context,
1679
- );
1680
-
1681
- const treasuryUtxo = await findRandomTreasuryUtxoWithOnlyAda(
1682
- context.lucid,
1683
- context.systemParams,
1684
- );
1685
-
1686
- const [__, treasuryValChange] = await getValueChangeAtAddressAfterAction(
1687
- context.lucid,
1688
- mkTreasuryAddr(context.lucid, context.systemParams),
1689
- async () =>
1690
- runAndAwaitTx(
1691
- context.lucid,
1692
- batchProcessStableswapOrders(
1693
- [stableswapOrder.utxo],
1694
- stableswapPool.utxo,
1695
- treasuryUtxo,
1696
- context.systemParams,
1697
- context.lucid,
1698
- ),
1699
- ),
1700
- );
1701
-
1702
- ///////////////////////////////////
1703
- // Checks after last transaction //
1704
- ///////////////////////////////////
1705
-
1706
- stableswapPool = await findStableswapPool(
1707
- context.lucid,
1708
- context.systemParams.validatorHashes.cdpHash,
1709
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
1710
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
1711
- EXAMPLE_TOKEN_1,
1712
- );
1713
-
1714
- const finalUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
1715
- addAssets(acc, utxo.assets),
1716
- )(await context.lucid.utxosAt(context.users.user.address));
1717
-
1718
- const userValueDiff = addAssets(
1719
- finalUserValue,
1720
- negateAssets(initialUserValue),
1721
- );
1722
-
1723
- const iassetAc = {
1724
- currencySymbol: fromHex(
1725
- context.systemParams.stableswapParams.iassetSymbol.unCurrencySymbol,
1726
- ),
1727
- tokenName: stableswapOrder.datum.iasset,
1728
- };
1729
-
1730
- assert(
1731
- assetClassValueOf(treasuryValChange, iassetAc) == 50_000_000n,
1732
- 'Unexpected iAsset value received by the treasury',
1733
- );
1734
-
1735
- assert(
1736
- assetClassValueOf(stableswapPool.utxo.assets, EXAMPLE_TOKEN_1) ==
1737
- 10_000_000n,
1738
- 'Unexpected value held by stableswap pool',
1739
- );
1740
-
1741
- assert(
1742
- assetClassValueOf(userValueDiff, iassetAc) == 10_000_000_000n - 50_000_000n,
1743
- 'Unexpected value received by order owner',
1744
- );
1745
- });
1746
-
1747
- test<IndigoTestContext>('Stableswap - Batch a single order to redeem assets with smaller scale', async (context: IndigoTestContext) => {
1748
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
1749
-
1750
- await runCreateStableswapPool(
1751
- context.assetConfigs[0].iassetTokenNameAscii,
1752
- EXAMPLE_TOKEN_1,
1753
- context,
1754
- rationalFromInt(1_000n),
1755
- );
1756
-
1757
- let stableswapPool = await findStableswapPool(
1758
- context.lucid,
1759
- context.systemParams.validatorHashes.cdpHash,
1760
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
1761
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
1762
- EXAMPLE_TOKEN_1,
1763
- );
1764
-
1765
- context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
1766
-
1767
- const initialUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
1768
- addAssets(acc, utxo.assets),
1769
- )(await context.lucid.utxosAt(context.users.user.address));
1770
-
1771
- // Mint iAsset to supply the pool with collateral asset.
1772
- // It also provides the treasury with a UTxO with iAsset.
1773
- await runAndAwaitTx(
1774
- context.lucid,
1775
- createStableswapOrder(
1776
- context.assetConfigs[0].iassetTokenNameAscii,
1777
- EXAMPLE_TOKEN_1,
1778
- 10_000_000n,
1779
- true,
1780
- stableswapPool.datum,
1781
- context.systemParams,
1782
- context.lucid,
1783
- ),
1784
- );
1785
-
1786
- let stableswapOrder = await findSingleStableswapOrder(
1787
- context.lucid,
1788
- context.systemParams.validatorHashes.stableswapHash,
1789
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
1790
- EXAMPLE_TOKEN_1,
1791
- );
1792
-
1793
- await createUtxoAtTreasury(
1794
- mkLovelacesOf(2_000_000n),
1795
- context.systemParams,
1796
- context,
1797
- );
1798
-
1799
- let treasuryUtxo = await findRandomTreasuryUtxoWithOnlyAda(
1800
- context.lucid,
1801
- context.systemParams,
1802
- );
1803
-
1804
- await runAndAwaitTx(
1805
- context.lucid,
1806
- batchProcessStableswapOrders(
1807
- [stableswapOrder.utxo],
1808
- stableswapPool.utxo,
1809
- treasuryUtxo,
1810
- context.systemParams,
1811
- context.lucid,
1812
- ),
1813
- );
1814
-
1815
- // Redeem part of the collateral asset previously supplied to the pool.
1816
- await runAndAwaitTx(
1817
- context.lucid,
1818
- createStableswapOrder(
1819
- context.assetConfigs[0].iassetTokenNameAscii,
1820
- EXAMPLE_TOKEN_1,
1821
- 5_000n,
1822
- false,
1823
- stableswapPool.datum,
1824
- context.systemParams,
1825
- context.lucid,
1826
- ),
1827
- );
1828
-
1829
- stableswapOrder = await findSingleStableswapOrder(
1830
- context.lucid,
1831
- context.systemParams.validatorHashes.stableswapHash,
1832
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
1833
- EXAMPLE_TOKEN_1,
1834
- );
1835
-
1836
- stableswapPool = await findStableswapPool(
1837
- context.lucid,
1838
- context.systemParams.validatorHashes.cdpHash,
1839
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
1840
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
1841
- EXAMPLE_TOKEN_1,
1842
- );
1843
-
1844
- const iassetAc = {
1845
- currencySymbol: fromHex(
1846
- context.systemParams.stableswapParams.iassetSymbol.unCurrencySymbol,
1847
- ),
1848
- tokenName: stableswapOrder.datum.iasset,
1849
- };
1850
-
1851
- treasuryUtxo = await findRandomTreasuryUtxoWithAsset(
1852
- context.lucid,
1853
- context.systemParams,
1854
- iassetAc,
1855
- );
1856
-
1857
- const [__, treasuryValChange] = await getValueChangeAtAddressAfterAction(
1858
- context.lucid,
1859
- mkTreasuryAddr(context.lucid, context.systemParams),
1860
- async () =>
1861
- runAndAwaitTx(
1862
- context.lucid,
1863
- batchProcessStableswapOrders(
1864
- [stableswapOrder.utxo],
1865
- stableswapPool.utxo,
1866
- treasuryUtxo,
1867
- context.systemParams,
1868
- context.lucid,
1869
- ),
1870
- ),
1871
- );
1872
-
1873
- ///////////////////////////////////
1874
- // Checks after last transaction //
1875
- ///////////////////////////////////
1876
-
1877
- stableswapPool = await findStableswapPool(
1878
- context.lucid,
1879
- context.systemParams.validatorHashes.cdpHash,
1880
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
1881
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
1882
- EXAMPLE_TOKEN_1,
1883
- );
1884
-
1885
- const finalUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
1886
- addAssets(acc, utxo.assets),
1887
- )(await context.lucid.utxosAt(context.users.user.address));
1888
-
1889
- const userValueDiff = addAssets(
1890
- finalUserValue,
1891
- negateAssets(initialUserValue),
1892
- );
1893
-
1894
- assert(
1895
- assetClassValueOf(treasuryValChange, iassetAc) == 25n &&
1896
- 0n <= lovelacesAmt(treasuryValChange) &&
1897
- lovelacesAmt(treasuryValChange) <= 9_000n,
1898
- 'Unexpected value received by the treasury',
1899
- );
1900
-
1901
- assert(
1902
- assetClassValueOf(stableswapPool.utxo.assets, EXAMPLE_TOKEN_1) ==
1903
- 10_000_000n - (5_000_000n - 25_000n),
1904
- 'Unexpected value held by stableswap pool',
1905
- );
1906
-
1907
- assert(
1908
- assetClassValueOf(userValueDiff, iassetAc) == 10_000n - 50n - 5_000n &&
1909
- assetClassValueOf(userValueDiff, EXAMPLE_TOKEN_1) ==
1910
- -10_000_000n + (5_000_000n - 25_000n),
1911
- 'Unexpected value received by order owner',
1912
- );
1913
- });
1914
-
1915
- test<IndigoTestContext>('Stableswap - Batch a single order to redeem assets with bigger scale', async (context: IndigoTestContext) => {
1916
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
1917
-
1918
- await runCreateStableswapPool(
1919
- context.assetConfigs[0].iassetTokenNameAscii,
1920
- EXAMPLE_TOKEN_1,
1921
- context,
1922
- { numerator: 1n, denominator: 1_000n },
1923
- );
1924
-
1925
- let stableswapPool = await findStableswapPool(
1926
- context.lucid,
1927
- context.systemParams.validatorHashes.cdpHash,
1928
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
1929
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
1930
- EXAMPLE_TOKEN_1,
1931
- );
1932
-
1933
- context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
1934
-
1935
- const initialUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
1936
- addAssets(acc, utxo.assets),
1937
- )(await context.lucid.utxosAt(context.users.user.address));
1938
-
1939
- // Mint iAsset to supply the pool with collateral asset.
1940
- // It also provides the treasury with a UTxO with iAsset.
1941
- await runAndAwaitTx(
1942
- context.lucid,
1943
- createStableswapOrder(
1944
- context.assetConfigs[0].iassetTokenNameAscii,
1945
- EXAMPLE_TOKEN_1,
1946
- 10_000_000n,
1947
- true,
1948
- stableswapPool.datum,
1949
- context.systemParams,
1950
- context.lucid,
1951
- ),
1952
- );
1953
-
1954
- let stableswapOrder = await findSingleStableswapOrder(
1955
- context.lucid,
1956
- context.systemParams.validatorHashes.stableswapHash,
1957
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
1958
- EXAMPLE_TOKEN_1,
1959
- );
1960
-
1961
- await createUtxoAtTreasury(
1962
- mkLovelacesOf(2_000_000n),
1963
- context.systemParams,
1964
- context,
1965
- );
1966
-
1967
- let treasuryUtxo = await findRandomTreasuryUtxoWithOnlyAda(
1968
- context.lucid,
1969
- context.systemParams,
1970
- );
1971
-
1972
- await runAndAwaitTx(
1973
- context.lucid,
1974
- batchProcessStableswapOrders(
1975
- [stableswapOrder.utxo],
1976
- stableswapPool.utxo,
1977
- treasuryUtxo,
1978
- context.systemParams,
1979
- context.lucid,
1980
- ),
1981
- );
1982
-
1983
- // Redeem part of the collateral asset previously supplied to the pool.
1984
- await runAndAwaitTx(
1985
- context.lucid,
1986
- createStableswapOrder(
1987
- context.assetConfigs[0].iassetTokenNameAscii,
1988
- EXAMPLE_TOKEN_1,
1989
- 5_000_000_000n,
1990
- false,
1991
- stableswapPool.datum,
1992
- context.systemParams,
1993
- context.lucid,
1994
- ),
1995
- );
1996
-
1997
- stableswapOrder = await findSingleStableswapOrder(
1998
- context.lucid,
1999
- context.systemParams.validatorHashes.stableswapHash,
2000
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
2001
- EXAMPLE_TOKEN_1,
2002
- );
2003
-
2004
- stableswapPool = await findStableswapPool(
2005
- context.lucid,
2006
- context.systemParams.validatorHashes.cdpHash,
2007
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
2008
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
2009
- EXAMPLE_TOKEN_1,
2010
- );
2011
-
2012
- const iassetAc = {
2013
- currencySymbol: fromHex(
2014
- context.systemParams.stableswapParams.iassetSymbol.unCurrencySymbol,
2015
- ),
2016
- tokenName: stableswapOrder.datum.iasset,
2017
- };
2018
-
2019
- treasuryUtxo = await findRandomTreasuryUtxoWithAsset(
2020
- context.lucid,
2021
- context.systemParams,
2022
- iassetAc,
2023
- );
2024
-
2025
- const [__, treasuryValChange] = await getValueChangeAtAddressAfterAction(
2026
- context.lucid,
2027
- mkTreasuryAddr(context.lucid, context.systemParams),
2028
- async () =>
2029
- runAndAwaitTx(
2030
- context.lucid,
2031
- batchProcessStableswapOrders(
2032
- [stableswapOrder.utxo],
2033
- stableswapPool.utxo,
2034
- treasuryUtxo,
2035
- context.systemParams,
2036
- context.lucid,
2037
- ),
2038
- ),
2039
- );
2040
-
2041
- ///////////////////////////////////
2042
- // Checks after last transaction //
2043
- ///////////////////////////////////
2044
-
2045
- stableswapPool = await findStableswapPool(
2046
- context.lucid,
2047
- context.systemParams.validatorHashes.cdpHash,
2048
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
2049
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
2050
- EXAMPLE_TOKEN_1,
2051
- );
2052
-
2053
- const finalUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
2054
- addAssets(acc, utxo.assets),
2055
- )(await context.lucid.utxosAt(context.users.user.address));
2056
-
2057
- const userValueDiff = addAssets(
2058
- finalUserValue,
2059
- negateAssets(initialUserValue),
2060
- );
2061
-
2062
- assert(
2063
- assetClassValueOf(treasuryValChange, iassetAc) == 25_000_000n &&
2064
- 0n <= lovelacesAmt(treasuryValChange) &&
2065
- lovelacesAmt(treasuryValChange) <= 9_000n,
2066
- 'Unexpected value received by the treasury',
2067
- );
2068
-
2069
- assert(
2070
- assetClassValueOf(stableswapPool.utxo.assets, EXAMPLE_TOKEN_1) ==
2071
- 10_000_000n - (5_000_000n - 25_000n),
2072
- 'Unexpected value held by stableswap pool',
2073
- );
2074
-
2075
- assert(
2076
- assetClassValueOf(userValueDiff, iassetAc) ==
2077
- 10_000_000_000n - 50_000_000n - 5_000_000_000n &&
2078
- assetClassValueOf(userValueDiff, EXAMPLE_TOKEN_1) ==
2079
- -10_000_000n + (5_000_000n - 25_000n),
2080
- 'Unexpected value received by order owner',
2081
- );
2082
- });
2083
-
2084
- test<IndigoTestContext>('Stableswap - Batch multiple orders to mint from same owner, 11', async (context: IndigoTestContext) => {
2085
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
2086
-
2087
- await runCreateStableswapPool(
2088
- context.assetConfigs[0].iassetTokenNameAscii,
2089
- EXAMPLE_TOKEN_1,
2090
- context,
2091
- );
2092
-
2093
- let stableswapPool = await findStableswapPool(
2094
- context.lucid,
2095
- context.systemParams.validatorHashes.cdpHash,
2096
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
2097
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
2098
- EXAMPLE_TOKEN_1,
2099
- );
2100
-
2101
- context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
2102
-
2103
- const initialUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
2104
- addAssets(acc, utxo.assets),
2105
- )(await context.lucid.utxosAt(context.users.user.address));
2106
-
2107
- const numberOfOrders = 11;
2108
-
2109
- await repeat(numberOfOrders, async () => {
2110
- await runAndAwaitTx(
2111
- context.lucid,
2112
- createStableswapOrder(
2113
- context.assetConfigs[0].iassetTokenNameAscii,
2114
- EXAMPLE_TOKEN_1,
2115
- 10_000_000n,
2116
- true,
2117
- stableswapPool.datum,
2118
- context.systemParams,
2119
- context.lucid,
2120
- ),
2121
- );
2122
- });
2123
-
2124
- const stableswapOrders = await findStableswapOrders(
2125
- context.lucid,
2126
- context.systemParams.validatorHashes.stableswapHash,
2127
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
2128
- EXAMPLE_TOKEN_1,
2129
- );
2130
-
2131
- await createUtxoAtTreasury(
2132
- mkLovelacesOf(2_000_000n),
2133
- context.systemParams,
2134
- context,
2135
- );
2136
-
2137
- const treasuryUtxo = await findRandomTreasuryUtxoWithOnlyAda(
2138
- context.lucid,
2139
- context.systemParams,
2140
- );
2141
-
2142
- const [__, treasuryValChange] = await getValueChangeAtAddressAfterAction(
2143
- context.lucid,
2144
- mkTreasuryAddr(context.lucid, context.systemParams),
2145
- async () =>
2146
- benchmarkAndAwaitTx(
2147
- 'Stableswap - Batch multiple orders to mint from same owner, 11',
2148
- await batchProcessStableswapOrders(
2149
- stableswapOrders.map((order) => order.utxo),
2150
- stableswapPool.utxo,
2151
- treasuryUtxo,
2152
- context.systemParams,
2153
- context.lucid,
2154
- ),
2155
- context.lucid,
2156
- context.emulator,
2157
- ),
2158
- );
2159
-
2160
- ///////////////////////////////////
2161
- // Checks after last transaction //
2162
- ///////////////////////////////////
2163
-
2164
- stableswapPool = await findStableswapPool(
2165
- context.lucid,
2166
- context.systemParams.validatorHashes.cdpHash,
2167
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
2168
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
2169
- EXAMPLE_TOKEN_1,
2170
- );
2171
-
2172
- const finalUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
2173
- addAssets(acc, utxo.assets),
2174
- )(await context.lucid.utxosAt(context.users.user.address));
2175
-
2176
- const userValueDiff = addAssets(
2177
- finalUserValue,
2178
- negateAssets(initialUserValue),
2179
- );
2180
-
2181
- const iassetAc = {
2182
- currencySymbol: fromHex(
2183
- context.systemParams.stableswapParams.iassetSymbol.unCurrencySymbol,
2184
- ),
2185
- tokenName: stableswapOrders[0].datum.iasset,
2186
- };
2187
-
2188
- assert(
2189
- assetClassValueOf(treasuryValChange, iassetAc) ==
2190
- BigInt(numberOfOrders) * 50_000n,
2191
- 'Unexpected iAsset value received by the treasury',
2192
- );
2193
-
2194
- assert(
2195
- assetClassValueOf(stableswapPool.utxo.assets, EXAMPLE_TOKEN_1) ==
2196
- BigInt(numberOfOrders) * 10_000_000n,
2197
- 'Unexpected value held by stableswap pool',
2198
- );
2199
-
2200
- assert(
2201
- assetClassValueOf(userValueDiff, iassetAc) ==
2202
- BigInt(numberOfOrders) * (10_000_000n - 50_000n),
2203
- 'Unexpected value received by order owner',
2204
- );
2205
- });
2206
-
2207
- test<IndigoTestContext>('Stableswap - Batch multiple orders to redeem from same owner, 9', async (context: IndigoTestContext) => {
2208
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
2209
-
2210
- await runCreateStableswapPool(
2211
- context.assetConfigs[0].iassetTokenNameAscii,
2212
- EXAMPLE_TOKEN_1,
2213
- context,
2214
- );
2215
-
2216
- let stableswapPool = await findStableswapPool(
2217
- context.lucid,
2218
- context.systemParams.validatorHashes.cdpHash,
2219
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
2220
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
2221
- EXAMPLE_TOKEN_1,
2222
- );
2223
-
2224
- context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
2225
-
2226
- const initialUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
2227
- addAssets(acc, utxo.assets),
2228
- )(await context.lucid.utxosAt(context.users.user.address));
2229
-
2230
- const numberOfOrders = 9;
2231
-
2232
- // Mint iAsset to supply the pool with collateral asset.
2233
- // It also provides the treasury with a UTxO with iAsset.
2234
- await runAndAwaitTx(
2235
- context.lucid,
2236
- createStableswapOrder(
2237
- context.assetConfigs[0].iassetTokenNameAscii,
2238
- EXAMPLE_TOKEN_1,
2239
- BigInt(numberOfOrders) * 10_000_000n,
2240
- true,
2241
- stableswapPool.datum,
2242
- context.systemParams,
2243
- context.lucid,
2244
- ),
2245
- );
2246
-
2247
- let stableswapOrders = await findStableswapOrders(
2248
- context.lucid,
2249
- context.systemParams.validatorHashes.stableswapHash,
2250
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
2251
- EXAMPLE_TOKEN_1,
2252
- );
2253
-
2254
- await createUtxoAtTreasury(
2255
- mkLovelacesOf(2_000_000n),
2256
- context.systemParams,
2257
- context,
2258
- );
2259
-
2260
- let treasuryUtxo = await findRandomTreasuryUtxoWithOnlyAda(
2261
- context.lucid,
2262
- context.systemParams,
2263
- );
2264
-
2265
- await runAndAwaitTx(
2266
- context.lucid,
2267
- batchProcessStableswapOrders(
2268
- stableswapOrders.map((order) => order.utxo),
2269
- stableswapPool.utxo,
2270
- treasuryUtxo,
2271
- context.systemParams,
2272
- context.lucid,
2273
- ),
2274
- );
2275
-
2276
- // Redeem part of the collateral asset previously supplied to the pool.
2277
- await repeat(numberOfOrders, async () => {
2278
- await runAndAwaitTx(
2279
- context.lucid,
2280
- createStableswapOrder(
2281
- context.assetConfigs[0].iassetTokenNameAscii,
2282
- EXAMPLE_TOKEN_1,
2283
- 5_000_000n,
2284
- false,
2285
- stableswapPool.datum,
2286
- context.systemParams,
2287
- context.lucid,
2288
- ),
2289
- );
2290
- });
2291
-
2292
- stableswapOrders = await findStableswapOrders(
2293
- context.lucid,
2294
- context.systemParams.validatorHashes.stableswapHash,
2295
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
2296
- EXAMPLE_TOKEN_1,
2297
- );
2298
-
2299
- stableswapPool = await findStableswapPool(
2300
- context.lucid,
2301
- context.systemParams.validatorHashes.cdpHash,
2302
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
2303
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
2304
- EXAMPLE_TOKEN_1,
2305
- );
2306
-
2307
- const iassetAc = {
2308
- currencySymbol: fromHex(
2309
- context.systemParams.stableswapParams.iassetSymbol.unCurrencySymbol,
2310
- ),
2311
- tokenName: stableswapOrders[0].datum.iasset,
2312
- };
2313
-
2314
- treasuryUtxo = await findRandomTreasuryUtxoWithAsset(
2315
- context.lucid,
2316
- context.systemParams,
2317
- iassetAc,
2318
- );
2319
-
2320
- const [__, treasuryValChange] = await getValueChangeAtAddressAfterAction(
2321
- context.lucid,
2322
- mkTreasuryAddr(context.lucid, context.systemParams),
2323
- async () =>
2324
- benchmarkAndAwaitTx(
2325
- 'Stableswap - Batch multiple orders to redeem from same owner, 9',
2326
- await batchProcessStableswapOrders(
2327
- stableswapOrders.map((order) => order.utxo),
2328
- stableswapPool.utxo,
2329
- treasuryUtxo,
2330
- context.systemParams,
2331
- context.lucid,
2332
- ),
2333
- context.lucid,
2334
- context.emulator,
2335
- ),
2336
- );
2337
-
2338
- ///////////////////////////////////
2339
- // Checks after last transaction //
2340
- ///////////////////////////////////
2341
-
2342
- stableswapPool = await findStableswapPool(
2343
- context.lucid,
2344
- context.systemParams.validatorHashes.cdpHash,
2345
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
2346
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
2347
- EXAMPLE_TOKEN_1,
2348
- );
2349
-
2350
- const finalUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
2351
- addAssets(acc, utxo.assets),
2352
- )(await context.lucid.utxosAt(context.users.user.address));
2353
-
2354
- const userValueDiff = addAssets(
2355
- finalUserValue,
2356
- negateAssets(initialUserValue),
2357
- );
2358
-
2359
- assert(
2360
- assetClassValueOf(treasuryValChange, iassetAc) ==
2361
- BigInt(numberOfOrders) * 25_000n &&
2362
- 0n <= lovelacesAmt(treasuryValChange) &&
2363
- lovelacesAmt(treasuryValChange) <= 9_000n,
2364
- 'Unexpected value received by the treasury',
2365
- );
2366
-
2367
- assert(
2368
- assetClassValueOf(stableswapPool.utxo.assets, EXAMPLE_TOKEN_1) ==
2369
- BigInt(numberOfOrders) * (10_000_000n - (5_000_000n - 25_000n)),
2370
- 'Unexpected value held by stableswap pool',
2371
- );
2372
-
2373
- assert(
2374
- assetClassValueOf(userValueDiff, iassetAc) ==
2375
- BigInt(numberOfOrders) * (10_000_000n - 50_000n - 5_000_000n) &&
2376
- assetClassValueOf(userValueDiff, EXAMPLE_TOKEN_1) ==
2377
- BigInt(numberOfOrders) * (-10_000_000n + (5_000_000n - 25_000n)),
2378
- 'Unexpected value received by order owner',
2379
- );
2380
- });
2381
-
2382
- test<IndigoTestContext>('Stableswap - Batch multiple orders to mint from different owners', async (context: IndigoTestContext) => {
2383
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
2384
-
2385
- await runCreateStableswapPool(
2386
- context.assetConfigs[0].iassetTokenNameAscii,
2387
- EXAMPLE_TOKEN_1,
2388
- context,
2389
- );
2390
-
2391
- let stableswapPool = await findStableswapPool(
2392
- context.lucid,
2393
- context.systemParams.validatorHashes.cdpHash,
2394
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
2395
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
2396
- EXAMPLE_TOKEN_1,
2397
- );
2398
-
2399
- const initialAdminValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
2400
- addAssets(acc, utxo.assets),
2401
- )(await context.lucid.utxosAt(context.users.admin.address));
2402
-
2403
- await runAndAwaitTx(
2404
- context.lucid,
2405
- createStableswapOrder(
2406
- context.assetConfigs[0].iassetTokenNameAscii,
2407
- EXAMPLE_TOKEN_1,
2408
- 10_000_000n,
2409
- true,
2410
- stableswapPool.datum,
2411
- context.systemParams,
2412
- context.lucid,
2413
- ),
2414
- );
2415
-
2416
- context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
2417
-
2418
- const initialUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
2419
- addAssets(acc, utxo.assets),
2420
- )(await context.lucid.utxosAt(context.users.user.address));
2421
-
2422
- await runAndAwaitTx(
2423
- context.lucid,
2424
- createStableswapOrder(
2425
- context.assetConfigs[0].iassetTokenNameAscii,
2426
- EXAMPLE_TOKEN_1,
2427
- 5_000_000n,
2428
- true,
2429
- stableswapPool.datum,
2430
- context.systemParams,
2431
- context.lucid,
2432
- ),
2433
- );
2434
-
2435
- const stableswapOrders = await findStableswapOrders(
2436
- context.lucid,
2437
- context.systemParams.validatorHashes.stableswapHash,
2438
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
2439
- EXAMPLE_TOKEN_1,
2440
- );
2441
-
2442
- await createUtxoAtTreasury(
2443
- mkLovelacesOf(2_000_000n),
2444
- context.systemParams,
2445
- context,
2446
- );
2447
-
2448
- const treasuryUtxo = await findRandomTreasuryUtxoWithOnlyAda(
2449
- context.lucid,
2450
- context.systemParams,
2451
- );
2452
-
2453
- const [__, treasuryValChange] = await getValueChangeAtAddressAfterAction(
2454
- context.lucid,
2455
- mkTreasuryAddr(context.lucid, context.systemParams),
2456
- async () =>
2457
- runAndAwaitTx(
2458
- context.lucid,
2459
- batchProcessStableswapOrders(
2460
- stableswapOrders.map((order) => order.utxo),
2461
- stableswapPool.utxo,
2462
- treasuryUtxo,
2463
- context.systemParams,
2464
- context.lucid,
2465
- ),
2466
- ),
2467
- );
2468
-
2469
- ///////////////////////////////////
2470
- // Checks after last transaction //
2471
- ///////////////////////////////////
2472
-
2473
- stableswapPool = await findStableswapPool(
2474
- context.lucid,
2475
- context.systemParams.validatorHashes.cdpHash,
2476
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
2477
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
2478
- EXAMPLE_TOKEN_1,
2479
- );
2480
-
2481
- const iassetAc = {
2482
- currencySymbol: fromHex(
2483
- context.systemParams.stableswapParams.iassetSymbol.unCurrencySymbol,
2484
- ),
2485
- tokenName: stableswapOrders[0].datum.iasset,
2486
- };
2487
-
2488
- const finalAdminValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
2489
- addAssets(acc, utxo.assets),
2490
- )(await context.lucid.utxosAt(context.users.admin.address));
2491
-
2492
- const finalUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
2493
- addAssets(acc, utxo.assets),
2494
- )(await context.lucid.utxosAt(context.users.user.address));
2495
-
2496
- const adminValueDiff = addAssets(
2497
- finalAdminValue,
2498
- negateAssets(initialAdminValue),
2499
- );
2500
-
2501
- const userValueDiff = addAssets(
2502
- finalUserValue,
2503
- negateAssets(initialUserValue),
2504
- );
2505
-
2506
- assert(
2507
- assetClassValueOf(treasuryValChange, iassetAc) == 50_000n + 25_000n,
2508
- 'Unexpected iAsset value received by the treasury',
2509
- );
2510
-
2511
- assert(
2512
- assetClassValueOf(stableswapPool.utxo.assets, EXAMPLE_TOKEN_1) ==
2513
- 10_000_000n + 5_000_000n,
2514
- 'Unexpected value held by stableswap pool',
2515
- );
2516
-
2517
- assert(
2518
- assetClassValueOf(adminValueDiff, iassetAc) == 10_000_000n - 50_000n &&
2519
- assetClassValueOf(adminValueDiff, EXAMPLE_TOKEN_1) == -10_000_000n,
2520
- 'Unexpected value received by order #1 owner',
2521
- );
2522
-
2523
- assert(
2524
- assetClassValueOf(userValueDiff, iassetAc) == 5_000_000n - 25_000n &&
2525
- assetClassValueOf(userValueDiff, EXAMPLE_TOKEN_1) == -5_000_000n,
2526
- 'Unexpected value received by order #2 owner',
2527
- );
2528
- });
2529
-
2530
- test<IndigoTestContext>('Stableswap - Batch multiple orders to mint with rounded amounts', async (context: IndigoTestContext) => {
2531
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
2532
-
2533
- await runCreateStableswapPool(
2534
- context.assetConfigs[0].iassetTokenNameAscii,
2535
- EXAMPLE_TOKEN_1,
2536
- context,
2537
- // 0.999991 relative price
2538
- { numerator: 1_000_000n, denominator: 1_000_009n },
2539
- //15% fee
2540
- { numerator: 15n, denominator: 100n },
2541
- );
2542
-
2543
- let stableswapPool = await findStableswapPool(
2544
- context.lucid,
2545
- context.systemParams.validatorHashes.cdpHash,
2546
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
2547
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
2548
- EXAMPLE_TOKEN_1,
2549
- );
2550
-
2551
- context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
2552
-
2553
- const initialUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
2554
- addAssets(acc, utxo.assets),
2555
- )(await context.lucid.utxosAt(context.users.user.address));
2556
-
2557
- const numberOfOrders = 10;
2558
-
2559
- await repeat(numberOfOrders, async () => {
2560
- await runAndAwaitTx(
2561
- context.lucid,
2562
- createStableswapOrder(
2563
- context.assetConfigs[0].iassetTokenNameAscii,
2564
- EXAMPLE_TOKEN_1,
2565
- // The eq. iAsset amount is 100,000.9, rounded to 100,000.
2566
- 100_000n,
2567
- true,
2568
- stableswapPool.datum,
2569
- context.systemParams,
2570
- context.lucid,
2571
- ),
2572
- );
2573
- });
2574
-
2575
- const stableswapOrders = await findStableswapOrders(
2576
- context.lucid,
2577
- context.systemParams.validatorHashes.stableswapHash,
2578
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
2579
- EXAMPLE_TOKEN_1,
2580
- );
2581
-
2582
- await createUtxoAtTreasury(
2583
- mkLovelacesOf(2_000_000n),
2584
- context.systemParams,
2585
- context,
2586
- );
2587
-
2588
- const treasuryUtxo = await findRandomTreasuryUtxoWithOnlyAda(
2589
- context.lucid,
2590
- context.systemParams,
2591
- );
2592
-
2593
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
2594
-
2595
- const initialAdminValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
2596
- addAssets(acc, utxo.assets),
2597
- )(await context.lucid.utxosAt(context.users.admin.address));
2598
-
2599
- const [__, treasuryValChange] = await getValueChangeAtAddressAfterAction(
2600
- context.lucid,
2601
- mkTreasuryAddr(context.lucid, context.systemParams),
2602
- async () =>
2603
- runAndAwaitTx(
2604
- context.lucid,
2605
- batchProcessStableswapOrders(
2606
- stableswapOrders.map((order) => order.utxo),
2607
- stableswapPool.utxo,
2608
- treasuryUtxo,
2609
- context.systemParams,
2610
- context.lucid,
2611
- ),
2612
- ),
2613
- );
2614
-
2615
- ///////////////////////////////////
2616
- // Checks after last transaction //
2617
- ///////////////////////////////////
2618
-
2619
- stableswapPool = await findStableswapPool(
2620
- context.lucid,
2621
- context.systemParams.validatorHashes.cdpHash,
2622
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
2623
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
2624
- EXAMPLE_TOKEN_1,
2625
- );
2626
-
2627
- const iassetAc = {
2628
- currencySymbol: fromHex(
2629
- context.systemParams.stableswapParams.iassetSymbol.unCurrencySymbol,
2630
- ),
2631
- tokenName: stableswapOrders[0].datum.iasset,
2632
- };
2633
-
2634
- const finalAdminValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
2635
- addAssets(acc, utxo.assets),
2636
- )(await context.lucid.utxosAt(context.users.admin.address));
2637
-
2638
- const finalUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
2639
- addAssets(acc, utxo.assets),
2640
- )(await context.lucid.utxosAt(context.users.user.address));
2641
-
2642
- const adminValueDiff = addAssets(
2643
- finalAdminValue,
2644
- negateAssets(initialAdminValue),
2645
- );
2646
-
2647
- const userValueDiff = addAssets(
2648
- finalUserValue,
2649
- negateAssets(initialUserValue),
2650
- );
2651
-
2652
- assert(
2653
- assetClassValueOf(treasuryValChange, iassetAc) ==
2654
- BigInt(numberOfOrders) * 15_000n,
2655
- 'Unexpected iAsset value received by the treasury',
2656
- );
2657
-
2658
- assert(
2659
- assetClassValueOf(stableswapPool.utxo.assets, EXAMPLE_TOKEN_1) ==
2660
- BigInt(numberOfOrders) * 100_000n,
2661
- 'Unexpected value held by stableswap pool',
2662
- );
2663
-
2664
- assert(
2665
- assetClassValueOf(userValueDiff, iassetAc) ==
2666
- BigInt(numberOfOrders) * (100_000n - 15_000n) &&
2667
- assetClassValueOf(userValueDiff, EXAMPLE_TOKEN_1) ==
2668
- BigInt(numberOfOrders) * -100_000n,
2669
- 'Unexpected value received by orders owner',
2670
- );
2671
-
2672
- assert(
2673
- assetClassValueOf(adminValueDiff, iassetAc) == 0n &&
2674
- assetClassValueOf(adminValueDiff, EXAMPLE_TOKEN_1) == 0n,
2675
- 'Unexpected value received by the admin',
2676
- );
2677
- });
2678
-
2679
- test<IndigoTestContext>('Stableswap - Batch orders to mint with insignificant value', async (context: IndigoTestContext) => {
2680
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
2681
-
2682
- await runCreateStableswapPool(
2683
- context.assetConfigs[0].iassetTokenNameAscii,
2684
- EXAMPLE_TOKEN_1,
2685
- context,
2686
- // The collateral asset has one more decimal place than the iAsset.
2687
- rationalFromInt(10n),
2688
- );
2689
-
2690
- let stableswapPool = await findStableswapPool(
2691
- context.lucid,
2692
- context.systemParams.validatorHashes.cdpHash,
2693
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
2694
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
2695
- EXAMPLE_TOKEN_1,
2696
- );
2697
-
2698
- context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
2699
-
2700
- const initialUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
2701
- addAssets(acc, utxo.assets),
2702
- )(await context.lucid.utxosAt(context.users.user.address));
2703
-
2704
- await runAndAwaitTx(
2705
- context.lucid,
2706
- createStableswapOrder(
2707
- context.assetConfigs[0].iassetTokenNameAscii,
2708
- EXAMPLE_TOKEN_1,
2709
- // 1.0000001 of collateral asset, equivalent to 1 iAsset.
2710
- 10_000_001n,
2711
- true,
2712
- stableswapPool.datum,
2713
- context.systemParams,
2714
- context.lucid,
2715
- ),
2716
- );
2717
-
2718
- const stableswapOrders = await findStableswapOrders(
2719
- context.lucid,
2720
- context.systemParams.validatorHashes.stableswapHash,
2721
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
2722
- EXAMPLE_TOKEN_1,
2723
- );
2724
-
2725
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
2726
-
2727
- await createUtxoAtTreasury(
2728
- mkLovelacesOf(2_000_000n),
2729
- context.systemParams,
2730
- context,
2731
- );
2732
-
2733
- const treasuryUtxo = await findRandomTreasuryUtxoWithOnlyAda(
2734
- context.lucid,
2735
- context.systemParams,
2736
- );
2737
-
2738
- const initialAdminValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
2739
- addAssets(acc, utxo.assets),
2740
- )(await context.lucid.utxosAt(context.users.admin.address));
2741
-
2742
- const [__, treasuryValChange] = await getValueChangeAtAddressAfterAction(
2743
- context.lucid,
2744
- mkTreasuryAddr(context.lucid, context.systemParams),
2745
- async () =>
2746
- runAndAwaitTx(
2747
- context.lucid,
2748
- batchProcessStableswapOrders(
2749
- stableswapOrders.map((order) => order.utxo),
2750
- stableswapPool.utxo,
2751
- treasuryUtxo,
2752
- context.systemParams,
2753
- context.lucid,
2754
- ),
2755
- ),
2756
- );
2757
-
2758
- ///////////////////////////////////
2759
- // Checks after last transaction //
2760
- ///////////////////////////////////
2761
-
2762
- stableswapPool = await findStableswapPool(
2763
- context.lucid,
2764
- context.systemParams.validatorHashes.cdpHash,
2765
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
2766
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
2767
- EXAMPLE_TOKEN_1,
2768
- );
2769
-
2770
- const iassetAc = {
2771
- currencySymbol: fromHex(
2772
- context.systemParams.stableswapParams.iassetSymbol.unCurrencySymbol,
2773
- ),
2774
- tokenName: stableswapOrders[0].datum.iasset,
2775
- };
2776
-
2777
- const finalAdminValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
2778
- addAssets(acc, utxo.assets),
2779
- )(await context.lucid.utxosAt(context.users.admin.address));
2780
-
2781
- const finalUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
2782
- addAssets(acc, utxo.assets),
2783
- )(await context.lucid.utxosAt(context.users.user.address));
2784
-
2785
- const adminValueDiff = addAssets(
2786
- finalAdminValue,
2787
- negateAssets(initialAdminValue),
2788
- );
2789
-
2790
- const userValueDiff = addAssets(
2791
- finalUserValue,
2792
- negateAssets(initialUserValue),
2793
- );
2794
-
2795
- assert(
2796
- assetClassValueOf(treasuryValChange, iassetAc) == 5_000n,
2797
- 'Unexpected iAsset value received by the treasury',
2798
- );
2799
-
2800
- assert(
2801
- assetClassValueOf(stableswapPool.utxo.assets, EXAMPLE_TOKEN_1) ==
2802
- 10_000_000n,
2803
- 'Unexpected value held by stableswap pool',
2804
- );
2805
-
2806
- assert(
2807
- assetClassValueOf(userValueDiff, iassetAc) == 1_000_000n - 5_000n &&
2808
- assetClassValueOf(userValueDiff, EXAMPLE_TOKEN_1) == -10_000_001n,
2809
- 'Unexpected value received by orders owner',
2810
- );
2811
-
2812
- assert(
2813
- assetClassValueOf(adminValueDiff, iassetAc) == 0n &&
2814
- assetClassValueOf(adminValueDiff, EXAMPLE_TOKEN_1) == 1n,
2815
- 'Unexpected value received by the admin',
2816
- );
2817
- });
2818
-
2819
- test<IndigoTestContext>('Stableswap - Batch multiple orders to redeem from different owners', async (context: IndigoTestContext) => {
2820
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
2821
-
2822
- await runCreateStableswapPool(
2823
- context.assetConfigs[0].iassetTokenNameAscii,
2824
- EXAMPLE_TOKEN_1,
2825
- context,
2826
- );
2827
-
2828
- let stableswapPool = await findStableswapPool(
2829
- context.lucid,
2830
- context.systemParams.validatorHashes.cdpHash,
2831
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
2832
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
2833
- EXAMPLE_TOKEN_1,
2834
- );
2835
-
2836
- const initialAdminValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
2837
- addAssets(acc, utxo.assets),
2838
- )(await context.lucid.utxosAt(context.users.admin.address));
2839
-
2840
- // Mint iAsset to supply the pool with collateral asset.
2841
- // It also provides the treasury with a UTxO with iAsset.
2842
- await runAndAwaitTx(
2843
- context.lucid,
2844
- createStableswapOrder(
2845
- context.assetConfigs[0].iassetTokenNameAscii,
2846
- EXAMPLE_TOKEN_1,
2847
- 10_000_000n,
2848
- true,
2849
- stableswapPool.datum,
2850
- context.systemParams,
2851
- context.lucid,
2852
- ),
2853
- );
2854
-
2855
- context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
2856
-
2857
- const initialUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
2858
- addAssets(acc, utxo.assets),
2859
- )(await context.lucid.utxosAt(context.users.user.address));
2860
-
2861
- // Mint iAsset to supply the pool with collateral asset.
2862
- await runAndAwaitTx(
2863
- context.lucid,
2864
- createStableswapOrder(
2865
- context.assetConfigs[0].iassetTokenNameAscii,
2866
- EXAMPLE_TOKEN_1,
2867
- 10_000_000n,
2868
- true,
2869
- stableswapPool.datum,
2870
- context.systemParams,
2871
- context.lucid,
2872
- ),
2873
- );
2874
-
2875
- let stableswapOrders = await findStableswapOrders(
2876
- context.lucid,
2877
- context.systemParams.validatorHashes.stableswapHash,
2878
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
2879
- EXAMPLE_TOKEN_1,
2880
- );
2881
-
2882
- await createUtxoAtTreasury(
2883
- mkLovelacesOf(2_000_000n),
2884
- context.systemParams,
2885
- context,
2886
- );
2887
-
2888
- let treasuryUtxo = await findRandomTreasuryUtxoWithOnlyAda(
2889
- context.lucid,
2890
- context.systemParams,
2891
- );
2892
-
2893
- await runAndAwaitTx(
2894
- context.lucid,
2895
- batchProcessStableswapOrders(
2896
- stableswapOrders.map((order) => order.utxo),
2897
- stableswapPool.utxo,
2898
- treasuryUtxo,
2899
- context.systemParams,
2900
- context.lucid,
2901
- ),
2902
- );
2903
-
2904
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
2905
-
2906
- // Redeem part of the collateral asset previously supplied to the pool.
2907
- await runAndAwaitTx(
2908
- context.lucid,
2909
- createStableswapOrder(
2910
- context.assetConfigs[0].iassetTokenNameAscii,
2911
- EXAMPLE_TOKEN_1,
2912
- 5_000_000n,
2913
- false,
2914
- stableswapPool.datum,
2915
- context.systemParams,
2916
- context.lucid,
2917
- ),
2918
- );
2919
-
2920
- context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
2921
-
2922
- // Redeem part of the collateral asset previously supplied to the pool.
2923
- await runAndAwaitTx(
2924
- context.lucid,
2925
- createStableswapOrder(
2926
- context.assetConfigs[0].iassetTokenNameAscii,
2927
- EXAMPLE_TOKEN_1,
2928
- 2_500_000n,
2929
- false,
2930
- stableswapPool.datum,
2931
- context.systemParams,
2932
- context.lucid,
2933
- ),
2934
- );
2935
-
2936
- stableswapOrders = await findStableswapOrders(
2937
- context.lucid,
2938
- context.systemParams.validatorHashes.stableswapHash,
2939
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
2940
- EXAMPLE_TOKEN_1,
2941
- );
2942
-
2943
- stableswapPool = await findStableswapPool(
2944
- context.lucid,
2945
- context.systemParams.validatorHashes.cdpHash,
2946
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
2947
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
2948
- EXAMPLE_TOKEN_1,
2949
- );
2950
-
2951
- const iassetAc = {
2952
- currencySymbol: fromHex(
2953
- context.systemParams.stableswapParams.iassetSymbol.unCurrencySymbol,
2954
- ),
2955
- tokenName: stableswapOrders[0].datum.iasset,
2956
- };
2957
-
2958
- treasuryUtxo = await findRandomTreasuryUtxoWithAsset(
2959
- context.lucid,
2960
- context.systemParams,
2961
- iassetAc,
2962
- );
2963
-
2964
- const [__, treasuryValChange] = await getValueChangeAtAddressAfterAction(
2965
- context.lucid,
2966
- mkTreasuryAddr(context.lucid, context.systemParams),
2967
- async () =>
2968
- runAndAwaitTx(
2969
- context.lucid,
2970
- batchProcessStableswapOrders(
2971
- stableswapOrders.map((order) => order.utxo),
2972
- stableswapPool.utxo,
2973
- treasuryUtxo,
2974
- context.systemParams,
2975
- context.lucid,
2976
- ),
2977
- ),
2978
- );
2979
-
2980
- ///////////////////////////////////
2981
- // Checks after last transaction //
2982
- ///////////////////////////////////
2983
-
2984
- stableswapPool = await findStableswapPool(
2985
- context.lucid,
2986
- context.systemParams.validatorHashes.cdpHash,
2987
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
2988
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
2989
- EXAMPLE_TOKEN_1,
2990
- );
2991
-
2992
- const finalAdminValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
2993
- addAssets(acc, utxo.assets),
2994
- )(await context.lucid.utxosAt(context.users.admin.address));
2995
-
2996
- const finalUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
2997
- addAssets(acc, utxo.assets),
2998
- )(await context.lucid.utxosAt(context.users.user.address));
2999
-
3000
- const adminValueDiff = addAssets(
3001
- finalAdminValue,
3002
- negateAssets(initialAdminValue),
3003
- );
3004
-
3005
- const userValueDiff = addAssets(
3006
- finalUserValue,
3007
- negateAssets(initialUserValue),
3008
- );
3009
-
3010
- const numberOfOrders = 2;
3011
-
3012
- assert(
3013
- assetClassValueOf(treasuryValChange, iassetAc) == 25_000n + 12_500n &&
3014
- 0n <= lovelacesAmt(treasuryValChange) &&
3015
- lovelacesAmt(treasuryValChange) <= 9_000n,
3016
- 'Unexpected value received by the treasury',
3017
- );
3018
-
3019
- assert(
3020
- assetClassValueOf(stableswapPool.utxo.assets, EXAMPLE_TOKEN_1) ==
3021
- BigInt(numberOfOrders) * 10_000_000n -
3022
- (5_000_000n - 25_000n) -
3023
- (2_500_000n - 12_500n),
3024
- 'Unexpected value held by stableswap pool',
3025
- );
3026
-
3027
- assert(
3028
- assetClassValueOf(adminValueDiff, iassetAc) ==
3029
- 10_000_000n - 50_000n - 5_000_000n &&
3030
- assetClassValueOf(adminValueDiff, EXAMPLE_TOKEN_1) ==
3031
- -10_000_000n + (5_000_000n - 25_000n),
3032
- 'Unexpected value received by order #1 owner',
3033
- );
3034
-
3035
- assert(
3036
- assetClassValueOf(userValueDiff, iassetAc) ==
3037
- 10_000_000n - 50_000n - 2_500_000n &&
3038
- assetClassValueOf(userValueDiff, EXAMPLE_TOKEN_1) ==
3039
- -10_000_000n + (2_500_000n - 12_500n),
3040
- 'Unexpected value received by order #2 owner',
3041
- );
3042
- });
3043
-
3044
- test<IndigoTestContext>('Stableswap - Batch multiple orders to redeem with rounded amounts', async (context: IndigoTestContext) => {
3045
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
3046
-
3047
- await runCreateStableswapPool(
3048
- context.assetConfigs[0].iassetTokenNameAscii,
3049
- EXAMPLE_TOKEN_1,
3050
- context,
3051
- // 1.000019 relative price
3052
- { numerator: 1_000_000n, denominator: 999_981n },
3053
- // 1% fee
3054
- { numerator: 1n, denominator: 100n },
3055
- // 0.0015% fee
3056
- { numerator: 15n, denominator: 1_000_000n },
3057
- );
3058
-
3059
- let stableswapPool = await findStableswapPool(
3060
- context.lucid,
3061
- context.systemParams.validatorHashes.cdpHash,
3062
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
3063
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
3064
- EXAMPLE_TOKEN_1,
3065
- );
3066
-
3067
- context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
3068
-
3069
- const numberOfOrders = 3;
3070
-
3071
- // Mint iAsset to supply the pool with collateral asset.
3072
- // It also provides the treasury with a UTxO with iAsset.
3073
- await runAndAwaitTx(
3074
- context.lucid,
3075
- createStableswapOrder(
3076
- context.assetConfigs[0].iassetTokenNameAscii,
3077
- EXAMPLE_TOKEN_1,
3078
- BigInt(numberOfOrders) * 200_000n,
3079
- true,
3080
- stableswapPool.datum,
3081
- context.systemParams,
3082
- context.lucid,
3083
- ),
3084
- );
3085
-
3086
- let stableswapOrders = await findStableswapOrders(
3087
- context.lucid,
3088
- context.systemParams.validatorHashes.stableswapHash,
3089
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
3090
- EXAMPLE_TOKEN_1,
3091
- );
3092
-
3093
- await createUtxoAtTreasury(
3094
- mkLovelacesOf(2_000_000n),
3095
- context.systemParams,
3096
- context,
3097
- );
3098
-
3099
- let treasuryUtxo = await findRandomTreasuryUtxoWithOnlyAda(
3100
- context.lucid,
3101
- context.systemParams,
3102
- );
3103
-
3104
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
3105
-
3106
- await runAndAwaitTx(
3107
- context.lucid,
3108
- batchProcessStableswapOrders(
3109
- stableswapOrders.map((order) => order.utxo),
3110
- stableswapPool.utxo,
3111
- treasuryUtxo,
3112
- context.systemParams,
3113
- context.lucid,
3114
- ),
3115
- );
3116
-
3117
- context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
3118
-
3119
- const initialUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
3120
- addAssets(acc, utxo.assets),
3121
- )(await context.lucid.utxosAt(context.users.user.address));
3122
-
3123
- // Redeem part of the collateral asset previously supplied to the pool.
3124
- await repeat(numberOfOrders, async () => {
3125
- await runAndAwaitTx(
3126
- context.lucid,
3127
- createStableswapOrder(
3128
- context.assetConfigs[0].iassetTokenNameAscii,
3129
- EXAMPLE_TOKEN_1,
3130
- // The fee will be 1.5 iAssets, rounded to 1.
3131
- // The equivalent collateral amt after fees is 100000.9000171, rounded to 100,000.
3132
- 100_000n,
3133
- false,
3134
- stableswapPool.datum,
3135
- context.systemParams,
3136
- context.lucid,
3137
- ),
3138
- );
3139
- });
3140
-
3141
- stableswapOrders = await findStableswapOrders(
3142
- context.lucid,
3143
- context.systemParams.validatorHashes.stableswapHash,
3144
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
3145
- EXAMPLE_TOKEN_1,
3146
- );
3147
-
3148
- stableswapPool = await findStableswapPool(
3149
- context.lucid,
3150
- context.systemParams.validatorHashes.cdpHash,
3151
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
3152
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
3153
- EXAMPLE_TOKEN_1,
3154
- );
3155
-
3156
- const iassetAc = {
3157
- currencySymbol: fromHex(
3158
- context.systemParams.stableswapParams.iassetSymbol.unCurrencySymbol,
3159
- ),
3160
- tokenName: stableswapOrders[0].datum.iasset,
3161
- };
3162
-
3163
- treasuryUtxo = await findRandomTreasuryUtxoWithAsset(
3164
- context.lucid,
3165
- context.systemParams,
3166
- iassetAc,
3167
- );
3168
-
3169
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
3170
-
3171
- const initialAdminValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
3172
- addAssets(acc, utxo.assets),
3173
- )(await context.lucid.utxosAt(context.users.admin.address));
3174
-
3175
- const [__, treasuryValChange] = await getValueChangeAtAddressAfterAction(
3176
- context.lucid,
3177
- mkTreasuryAddr(context.lucid, context.systemParams),
3178
- async () =>
3179
- await runAndAwaitTx(
3180
- context.lucid,
3181
- batchProcessStableswapOrders(
3182
- stableswapOrders.map((order) => order.utxo),
3183
- stableswapPool.utxo,
3184
- treasuryUtxo,
3185
- context.systemParams,
3186
- context.lucid,
3187
- ),
3188
- ),
3189
- );
3190
-
3191
- ///////////////////////////////////
3192
- // Checks after last transaction //
3193
- ///////////////////////////////////
3194
-
3195
- stableswapPool = await findStableswapPool(
3196
- context.lucid,
3197
- context.systemParams.validatorHashes.cdpHash,
3198
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
3199
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
3200
- EXAMPLE_TOKEN_1,
3201
- );
3202
-
3203
- const finalUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
3204
- addAssets(acc, utxo.assets),
3205
- )(await context.lucid.utxosAt(context.users.user.address));
3206
-
3207
- const finalAdminValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
3208
- addAssets(acc, utxo.assets),
3209
- )(await context.lucid.utxosAt(context.users.admin.address));
3210
-
3211
- const userValueDiff = addAssets(
3212
- finalUserValue,
3213
- negateAssets(initialUserValue),
3214
- );
3215
-
3216
- const adminValueDiff = addAssets(
3217
- finalAdminValue,
3218
- negateAssets(initialAdminValue),
3219
- );
3220
-
3221
- assert(
3222
- assetClassValueOf(treasuryValChange, iassetAc) ==
3223
- BigInt(numberOfOrders) * 1n &&
3224
- 0n <= lovelacesAmt(treasuryValChange) &&
3225
- lovelacesAmt(treasuryValChange) <= 9_000n,
3226
- 'Unexpected value received by the treasury',
3227
- );
3228
-
3229
- assert(
3230
- assetClassValueOf(stableswapPool.utxo.assets, EXAMPLE_TOKEN_1) ==
3231
- BigInt(numberOfOrders) * (200_000n - 100_000n),
3232
- 'Unexpected value held by stableswap pool',
3233
- );
3234
-
3235
- assert(
3236
- assetClassValueOf(userValueDiff, iassetAc) ==
3237
- BigInt(numberOfOrders) * -100_000n &&
3238
- assetClassValueOf(userValueDiff, EXAMPLE_TOKEN_1) ==
3239
- BigInt(numberOfOrders) * 100_000n,
3240
- 'Unexpected value received by order owner',
3241
- );
3242
-
3243
- assert(
3244
- assetClassValueOf(adminValueDiff, iassetAc) == 0n &&
3245
- assetClassValueOf(adminValueDiff, EXAMPLE_TOKEN_1) == 0n,
3246
- 'Unexpected value received by the admin',
3247
- );
3248
- });
3249
-
3250
- test<IndigoTestContext>('Stableswap - Batch an order to redeem with insignificant value', async (context: IndigoTestContext) => {
3251
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
3252
-
3253
- await runCreateStableswapPool(
3254
- context.assetConfigs[0].iassetTokenNameAscii,
3255
- EXAMPLE_TOKEN_1,
3256
- context,
3257
- // The iAsset has one more decimal place than the collateral asset.
3258
- { numerator: 1n, denominator: 10n },
3259
- );
3260
-
3261
- let stableswapPool = await findStableswapPool(
3262
- context.lucid,
3263
- context.systemParams.validatorHashes.cdpHash,
3264
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
3265
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
3266
- EXAMPLE_TOKEN_1,
3267
- );
3268
-
3269
- context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
3270
-
3271
- // Mint iAsset to supply the pool with collateral asset.
3272
- // It also provides the treasury with a UTxO with iAsset.
3273
- await runAndAwaitTx(
3274
- context.lucid,
3275
- createStableswapOrder(
3276
- context.assetConfigs[0].iassetTokenNameAscii,
3277
- EXAMPLE_TOKEN_1,
3278
- 2_000_000n,
3279
- true,
3280
- stableswapPool.datum,
3281
- context.systemParams,
3282
- context.lucid,
3283
- ),
3284
- );
3285
-
3286
- let stableswapOrders = await findStableswapOrders(
3287
- context.lucid,
3288
- context.systemParams.validatorHashes.stableswapHash,
3289
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
3290
- EXAMPLE_TOKEN_1,
3291
- );
3292
-
3293
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
3294
-
3295
- await createUtxoAtTreasury(
3296
- mkLovelacesOf(2_000_000n),
3297
- context.systemParams,
3298
- context,
3299
- );
3300
-
3301
- let treasuryUtxo = await findRandomTreasuryUtxoWithOnlyAda(
3302
- context.lucid,
3303
- context.systemParams,
3304
- );
3305
-
3306
- await runAndAwaitTx(
3307
- context.lucid,
3308
- batchProcessStableswapOrders(
3309
- stableswapOrders.map((order) => order.utxo),
3310
- stableswapPool.utxo,
3311
- treasuryUtxo,
3312
- context.systemParams,
3313
- context.lucid,
3314
- ),
3315
- );
3316
-
3317
- context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
3318
-
3319
- const initialUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
3320
- addAssets(acc, utxo.assets),
3321
- )(await context.lucid.utxosAt(context.users.user.address));
3322
-
3323
- // Redeem part of the collateral asset previously supplied to the pool.
3324
- await runAndAwaitTx(
3325
- context.lucid,
3326
- createStableswapOrder(
3327
- context.assetConfigs[0].iassetTokenNameAscii,
3328
- EXAMPLE_TOKEN_1,
3329
- // 1.000001 of iAsset, equivalent to 1 collateral asset.
3330
- 10_000_001n,
3331
- false,
3332
- stableswapPool.datum,
3333
- context.systemParams,
3334
- context.lucid,
3335
- ),
3336
- );
3337
-
3338
- stableswapOrders = await findStableswapOrders(
3339
- context.lucid,
3340
- context.systemParams.validatorHashes.stableswapHash,
3341
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
3342
- EXAMPLE_TOKEN_1,
3343
- );
3344
-
3345
- stableswapPool = await findStableswapPool(
3346
- context.lucid,
3347
- context.systemParams.validatorHashes.cdpHash,
3348
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
3349
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
3350
- EXAMPLE_TOKEN_1,
3351
- );
3352
-
3353
- const iassetAc = {
3354
- currencySymbol: fromHex(
3355
- context.systemParams.stableswapParams.iassetSymbol.unCurrencySymbol,
3356
- ),
3357
- tokenName: stableswapOrders[0].datum.iasset,
3358
- };
3359
-
3360
- treasuryUtxo = await findRandomTreasuryUtxoWithAsset(
3361
- context.lucid,
3362
- context.systemParams,
3363
- iassetAc,
3364
- );
3365
-
3366
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
3367
-
3368
- const initialAdminValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
3369
- addAssets(acc, utxo.assets),
3370
- )(await context.lucid.utxosAt(context.users.admin.address));
3371
-
3372
- const [__, treasuryValChange] = await getValueChangeAtAddressAfterAction(
3373
- context.lucid,
3374
- mkTreasuryAddr(context.lucid, context.systemParams),
3375
- async () =>
3376
- await runAndAwaitTx(
3377
- context.lucid,
3378
- batchProcessStableswapOrders(
3379
- stableswapOrders.map((order) => order.utxo),
3380
- stableswapPool.utxo,
3381
- treasuryUtxo,
3382
- context.systemParams,
3383
- context.lucid,
3384
- ),
3385
- ),
3386
- );
3387
-
3388
- ///////////////////////////////////
3389
- // Checks after last transaction //
3390
- ///////////////////////////////////
3391
-
3392
- stableswapPool = await findStableswapPool(
3393
- context.lucid,
3394
- context.systemParams.validatorHashes.cdpHash,
3395
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
3396
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
3397
- EXAMPLE_TOKEN_1,
3398
- );
3399
-
3400
- const finalUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
3401
- addAssets(acc, utxo.assets),
3402
- )(await context.lucid.utxosAt(context.users.user.address));
3403
-
3404
- const finalAdminValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
3405
- addAssets(acc, utxo.assets),
3406
- )(await context.lucid.utxosAt(context.users.admin.address));
3407
-
3408
- const userValueDiff = addAssets(
3409
- finalUserValue,
3410
- negateAssets(initialUserValue),
3411
- );
3412
-
3413
- const adminValueDiff = addAssets(
3414
- finalAdminValue,
3415
- negateAssets(initialAdminValue),
3416
- );
3417
-
3418
- assert(
3419
- assetClassValueOf(treasuryValChange, iassetAc) == 50_000n &&
3420
- 0n <= lovelacesAmt(treasuryValChange) &&
3421
- lovelacesAmt(treasuryValChange) <= 9_000n,
3422
- 'Unexpected value received by the treasury',
3423
- );
3424
-
3425
- assert(
3426
- assetClassValueOf(stableswapPool.utxo.assets, EXAMPLE_TOKEN_1) ==
3427
- 2_000_000n - 1_000_000n + 5_000n,
3428
- 'Unexpected value held by stableswap pool',
3429
- );
3430
-
3431
- assert(
3432
- assetClassValueOf(userValueDiff, iassetAc) == -10_000_001n &&
3433
- assetClassValueOf(userValueDiff, EXAMPLE_TOKEN_1) == 1_000_000n - 5_000n,
3434
- 'Unexpected value received by order owner',
3435
- );
3436
-
3437
- assert(
3438
- assetClassValueOf(adminValueDiff, iassetAc) == 1n &&
3439
- assetClassValueOf(adminValueDiff, EXAMPLE_TOKEN_1) == 0n,
3440
- 'Unexpected value received by the admin',
3441
- );
3442
- });
3443
-
3444
- test<IndigoTestContext>('Stableswap - Batch an order to mint with an order to redeem', async (context: IndigoTestContext) => {
3445
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
3446
-
3447
- await runCreateStableswapPool(
3448
- context.assetConfigs[0].iassetTokenNameAscii,
3449
- EXAMPLE_TOKEN_1,
3450
- context,
3451
- );
3452
-
3453
- let stableswapPool = await findStableswapPool(
3454
- context.lucid,
3455
- context.systemParams.validatorHashes.cdpHash,
3456
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
3457
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
3458
- EXAMPLE_TOKEN_1,
3459
- );
3460
-
3461
- // Mint iAsset to supply the pool with collateral asset.
3462
- // It also provides the treasury with a UTxO with iAsset.
3463
- await runAndAwaitTx(
3464
- context.lucid,
3465
- createStableswapOrder(
3466
- context.assetConfigs[0].iassetTokenNameAscii,
3467
- EXAMPLE_TOKEN_1,
3468
- 20_000_000n,
3469
- true,
3470
- stableswapPool.datum,
3471
- context.systemParams,
3472
- context.lucid,
3473
- ),
3474
- );
3475
-
3476
- let stableswapOrders = await findStableswapOrders(
3477
- context.lucid,
3478
- context.systemParams.validatorHashes.stableswapHash,
3479
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
3480
- EXAMPLE_TOKEN_1,
3481
- );
3482
-
3483
- await createUtxoAtTreasury(
3484
- mkLovelacesOf(2_000_000n),
3485
- context.systemParams,
3486
- context,
3487
- );
3488
-
3489
- let treasuryUtxo = await findRandomTreasuryUtxoWithOnlyAda(
3490
- context.lucid,
3491
- context.systemParams,
3492
- );
3493
-
3494
- await runAndAwaitTx(
3495
- context.lucid,
3496
- batchProcessStableswapOrders(
3497
- stableswapOrders.map((order) => order.utxo),
3498
- stableswapPool.utxo,
3499
- treasuryUtxo,
3500
- context.systemParams,
3501
- context.lucid,
3502
- ),
3503
- );
3504
-
3505
- const initialAdminValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
3506
- addAssets(acc, utxo.assets),
3507
- )(await context.lucid.utxosAt(context.users.admin.address));
3508
-
3509
- // Order to redeem.
3510
- await runAndAwaitTx(
3511
- context.lucid,
3512
- createStableswapOrder(
3513
- context.assetConfigs[0].iassetTokenNameAscii,
3514
- EXAMPLE_TOKEN_1,
3515
- 10_000_000n,
3516
- false,
3517
- stableswapPool.datum,
3518
- context.systemParams,
3519
- context.lucid,
3520
- ),
3521
- );
3522
-
3523
- context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
3524
-
3525
- const initialUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
3526
- addAssets(acc, utxo.assets),
3527
- )(await context.lucid.utxosAt(context.users.user.address));
3528
-
3529
- // Order to mint.
3530
- await runAndAwaitTx(
3531
- context.lucid,
3532
- createStableswapOrder(
3533
- context.assetConfigs[0].iassetTokenNameAscii,
3534
- EXAMPLE_TOKEN_1,
3535
- 10_000_000n,
3536
- true,
3537
- stableswapPool.datum,
3538
- context.systemParams,
3539
- context.lucid,
3540
- ),
3541
- );
3542
-
3543
- stableswapOrders = await findStableswapOrders(
3544
- context.lucid,
3545
- context.systemParams.validatorHashes.stableswapHash,
3546
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
3547
- EXAMPLE_TOKEN_1,
3548
- );
3549
-
3550
- stableswapPool = await findStableswapPool(
3551
- context.lucid,
3552
- context.systemParams.validatorHashes.cdpHash,
3553
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
3554
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
3555
- EXAMPLE_TOKEN_1,
3556
- );
3557
-
3558
- const iassetAc = {
3559
- currencySymbol: fromHex(
3560
- context.systemParams.stableswapParams.iassetSymbol.unCurrencySymbol,
3561
- ),
3562
- tokenName: stableswapOrders[0].datum.iasset,
3563
- };
3564
-
3565
- treasuryUtxo = await findRandomTreasuryUtxoWithAsset(
3566
- context.lucid,
3567
- context.systemParams,
3568
- iassetAc,
3569
- );
3570
-
3571
- const [__, treasuryValChange] = await getValueChangeAtAddressAfterAction(
3572
- context.lucid,
3573
- mkTreasuryAddr(context.lucid, context.systemParams),
3574
- async () =>
3575
- runAndAwaitTx(
3576
- context.lucid,
3577
- batchProcessStableswapOrders(
3578
- stableswapOrders.map((order) => order.utxo),
3579
- stableswapPool.utxo,
3580
- treasuryUtxo,
3581
- context.systemParams,
3582
- context.lucid,
3583
- ),
3584
- ),
3585
- );
3586
-
3587
- ///////////////////////////////////
3588
- // Checks after last transaction //
3589
- ///////////////////////////////////
3590
-
3591
- stableswapPool = await findStableswapPool(
3592
- context.lucid,
3593
- context.systemParams.validatorHashes.cdpHash,
3594
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
3595
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
3596
- EXAMPLE_TOKEN_1,
3597
- );
3598
-
3599
- const finalAdminValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
3600
- addAssets(acc, utxo.assets),
3601
- )(await context.lucid.utxosAt(context.users.admin.address));
3602
-
3603
- const finalUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
3604
- addAssets(acc, utxo.assets),
3605
- )(await context.lucid.utxosAt(context.users.user.address));
3606
-
3607
- const adminValueDiff = addAssets(
3608
- finalAdminValue,
3609
- negateAssets(initialAdminValue),
3610
- );
3611
-
3612
- const userValueDiff = addAssets(
3613
- finalUserValue,
3614
- negateAssets(initialUserValue),
3615
- );
3616
-
3617
- assert(
3618
- assetClassValueOf(treasuryValChange, iassetAc) == 50_000n + 50_000n &&
3619
- 0n <= lovelacesAmt(treasuryValChange) &&
3620
- lovelacesAmt(treasuryValChange) <= 9_000n,
3621
- 'Unexpected value received by the treasury',
3622
- );
3623
-
3624
- // The first 20_000_000 come from the minting order processed before the batch.
3625
- assert(
3626
- assetClassValueOf(stableswapPool.utxo.assets, EXAMPLE_TOKEN_1) ==
3627
- 20_000_000n + 50_000n,
3628
- 'Unexpected collateral asset value held by stableswap pool',
3629
- );
3630
-
3631
- assert(
3632
- assetClassValueOf(userValueDiff, iassetAc) == 10_000_000n - 50_000n &&
3633
- assetClassValueOf(userValueDiff, EXAMPLE_TOKEN_1) == -10_000_000n,
3634
- 'Unexpected value received by minting order owner',
3635
- );
3636
-
3637
- assert(
3638
- assetClassValueOf(adminValueDiff, iassetAc) == -10_000_000n &&
3639
- assetClassValueOf(adminValueDiff, EXAMPLE_TOKEN_1) ==
3640
- 10_000_000n - 50_000n,
3641
- 'Unexpected value received by redeeming order owner',
3642
- );
3643
- });
3644
-
3645
- test<IndigoTestContext>('Stableswap - Batch an order to mint with an order to redeem (with destination datum)', async (context: IndigoTestContext) => {
3646
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
3647
-
3648
- await runCreateStableswapPool(
3649
- context.assetConfigs[0].iassetTokenNameAscii,
3650
- EXAMPLE_TOKEN_1,
3651
- context,
3652
- );
3653
-
3654
- let stableswapPool = await findStableswapPool(
3655
- context.lucid,
3656
- context.systemParams.validatorHashes.cdpHash,
3657
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
3658
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
3659
- EXAMPLE_TOKEN_1,
3660
- );
3661
-
3662
- // Mint iAsset to supply the pool with collateral asset.
3663
- // It also provides the treasury with a UTxO with iAsset.
3664
- await runAndAwaitTx(
3665
- context.lucid,
3666
- createStableswapOrder(
3667
- context.assetConfigs[0].iassetTokenNameAscii,
3668
- EXAMPLE_TOKEN_1,
3669
- 20_000_000n,
3670
- true,
3671
- stableswapPool.datum,
3672
- context.systemParams,
3673
- context.lucid,
3674
- undefined,
3675
- Data.fromCBORHex('d87980'),
3676
- ),
3677
- );
3678
-
3679
- let stableswapOrders = await findStableswapOrders(
3680
- context.lucid,
3681
- context.systemParams.validatorHashes.stableswapHash,
3682
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
3683
- EXAMPLE_TOKEN_1,
3684
- );
3685
-
3686
- await createUtxoAtTreasury(
3687
- mkLovelacesOf(2_000_000n),
3688
- context.systemParams,
3689
- context,
3690
- );
3691
-
3692
- let treasuryUtxo = await findRandomTreasuryUtxoWithOnlyAda(
3693
- context.lucid,
3694
- context.systemParams,
3695
- );
3696
-
3697
- await runAndAwaitTx(
3698
- context.lucid,
3699
- batchProcessStableswapOrders(
3700
- stableswapOrders.map((order) => order.utxo),
3701
- stableswapPool.utxo,
3702
- treasuryUtxo,
3703
- context.systemParams,
3704
- context.lucid,
3705
- ),
3706
- );
3707
-
3708
- const initialAdminValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
3709
- addAssets(acc, utxo.assets),
3710
- )(await context.lucid.utxosAt(context.users.admin.address));
3711
-
3712
- // Order to redeem.
3713
- await runAndAwaitTx(
3714
- context.lucid,
3715
- createStableswapOrder(
3716
- context.assetConfigs[0].iassetTokenNameAscii,
3717
- EXAMPLE_TOKEN_1,
3718
- 10_000_000n,
3719
- false,
3720
- stableswapPool.datum,
3721
- context.systemParams,
3722
- context.lucid,
3723
- undefined,
3724
- Data.fromCBORHex('d87980'),
3725
- ),
3726
- );
3727
-
3728
- context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
3729
-
3730
- const initialUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
3731
- addAssets(acc, utxo.assets),
3732
- )(await context.lucid.utxosAt(context.users.user.address));
3733
-
3734
- // Order to mint.
3735
- await runAndAwaitTx(
3736
- context.lucid,
3737
- createStableswapOrder(
3738
- context.assetConfigs[0].iassetTokenNameAscii,
3739
- EXAMPLE_TOKEN_1,
3740
- 10_000_000n,
3741
- true,
3742
- stableswapPool.datum,
3743
- context.systemParams,
3744
- context.lucid,
3745
- undefined,
3746
- Data.fromCBORHex('d87a80'),
3747
- ),
3748
- );
3749
-
3750
- stableswapOrders = await findStableswapOrders(
3751
- context.lucid,
3752
- context.systemParams.validatorHashes.stableswapHash,
3753
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
3754
- EXAMPLE_TOKEN_1,
3755
- );
3756
-
3757
- stableswapPool = await findStableswapPool(
3758
- context.lucid,
3759
- context.systemParams.validatorHashes.cdpHash,
3760
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
3761
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
3762
- EXAMPLE_TOKEN_1,
3763
- );
3764
-
3765
- const iassetAc = {
3766
- currencySymbol: fromHex(
3767
- context.systemParams.stableswapParams.iassetSymbol.unCurrencySymbol,
3768
- ),
3769
- tokenName: stableswapOrders[0].datum.iasset,
3770
- };
3771
-
3772
- treasuryUtxo = await findRandomTreasuryUtxoWithAsset(
3773
- context.lucid,
3774
- context.systemParams,
3775
- iassetAc,
3776
- );
3777
-
3778
- const [__, treasuryValChange] = await getValueChangeAtAddressAfterAction(
3779
- context.lucid,
3780
- mkTreasuryAddr(context.lucid, context.systemParams),
3781
- async () =>
3782
- runAndAwaitTx(
3783
- context.lucid,
3784
- batchProcessStableswapOrders(
3785
- stableswapOrders.map((order) => order.utxo),
3786
- stableswapPool.utxo,
3787
- treasuryUtxo,
3788
- context.systemParams,
3789
- context.lucid,
3790
- ),
3791
- ),
3792
- );
3793
-
3794
- ///////////////////////////////////
3795
- // Checks after last transaction //
3796
- ///////////////////////////////////
3797
-
3798
- stableswapPool = await findStableswapPool(
3799
- context.lucid,
3800
- context.systemParams.validatorHashes.cdpHash,
3801
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
3802
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
3803
- EXAMPLE_TOKEN_1,
3804
- );
3805
-
3806
- const finalAdminValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
3807
- addAssets(acc, utxo.assets),
3808
- )(await context.lucid.utxosAt(context.users.admin.address));
3809
-
3810
- const finalUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
3811
- addAssets(acc, utxo.assets),
3812
- )(await context.lucid.utxosAt(context.users.user.address));
3813
-
3814
- const adminValueDiff = addAssets(
3815
- finalAdminValue,
3816
- negateAssets(initialAdminValue),
3817
- );
3818
-
3819
- const userValueDiff = addAssets(
3820
- finalUserValue,
3821
- negateAssets(initialUserValue),
3822
- );
3823
-
3824
- assert(
3825
- assetClassValueOf(treasuryValChange, iassetAc) == 50_000n + 50_000n &&
3826
- 0n <= lovelacesAmt(treasuryValChange) &&
3827
- lovelacesAmt(treasuryValChange) <= 9_000n,
3828
- 'Unexpected value received by the treasury',
3829
- );
3830
-
3831
- // This comes from the minting order processed before the batch.
3832
- assert(
3833
- assetClassValueOf(stableswapPool.utxo.assets, EXAMPLE_TOKEN_1) ==
3834
- 20_000_000n + 50_000n,
3835
- 'Unexpected value held by stableswap pool',
3836
- );
3837
-
3838
- assert(
3839
- assetClassValueOf(userValueDiff, iassetAc) == 10_000_000n - 50_000n &&
3840
- assetClassValueOf(userValueDiff, EXAMPLE_TOKEN_1) == -10_000_000n,
3841
- 'Unexpected value received by minting order owner',
3842
- );
3843
-
3844
- assert(
3845
- assetClassValueOf(adminValueDiff, iassetAc) == -10_000_000n &&
3846
- assetClassValueOf(adminValueDiff, EXAMPLE_TOKEN_1) ==
3847
- 10_000_000n - 50_000n,
3848
- 'Unexpected value received by redeeming order owner',
3849
- );
3850
- });
3851
-
3852
- test<IndigoTestContext>('Stableswap - Batch an order to mint with an order to redeem with an empty pool', async (context: IndigoTestContext) => {
3853
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
3854
-
3855
- await runCreateStableswapPool(
3856
- context.assetConfigs[0].iassetTokenNameAscii,
3857
- EXAMPLE_TOKEN_1,
3858
- context,
3859
- );
3860
-
3861
- let stableswapPool = await findStableswapPool(
3862
- context.lucid,
3863
- context.systemParams.validatorHashes.cdpHash,
3864
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
3865
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
3866
- EXAMPLE_TOKEN_1,
3867
- );
3868
-
3869
- let orefs = await findAllNecessaryOrefs(
3870
- context.lucid,
3871
- context.systemParams,
3872
- context.assetConfigs[0].iassetTokenNameAscii,
3873
- context.assetConfigs[0].collateralAssets[0].collateralAsset,
3874
- );
3875
- const priceOracleUtxo = await findPriceOracleFromCollateralAsset(
3876
- context.lucid,
3877
- orefs.collateralAsset,
3878
- );
3879
-
3880
- await runAndAwaitTx(
3881
- context.lucid,
3882
- feedPriceOracleTx(
3883
- context.lucid,
3884
- priceOracleUtxo!,
3885
- rationalFromInt(1n),
3886
- context.assetConfigs[0].collateralAssets[0].oracleParams!,
3887
- ),
3888
- );
3889
-
3890
- const initialAdminValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
3891
- addAssets(acc, utxo.assets),
3892
- )(await context.lucid.utxosAt(context.users.admin.address));
3893
-
3894
- // Order to mint.
3895
- await runAndAwaitTx(
3896
- context.lucid,
3897
- createStableswapOrder(
3898
- context.assetConfigs[0].iassetTokenNameAscii,
3899
- EXAMPLE_TOKEN_1,
3900
- 10_000_000n,
3901
- true,
3902
- stableswapPool.datum,
3903
- context.systemParams,
3904
- context.lucid,
3905
- ),
3906
- );
3907
-
3908
- context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
3909
-
3910
- orefs = await findAllNecessaryOrefs(
3911
- context.lucid,
3912
- context.systemParams,
3913
- context.assetConfigs[0].iassetTokenNameAscii,
3914
- context.assetConfigs[0].collateralAssets[0].collateralAsset,
3915
- );
3916
-
3917
- // Get some iAsset to be able to redeem from stableswap pool.
3918
- await runAndAwaitTx(
3919
- context.lucid,
3920
- runOpenCdp(
3921
- context,
3922
- context.systemParams,
3923
- context.assetConfigs[0].iassetTokenNameAscii,
3924
- context.assetConfigs[0].collateralAssets[0].collateralAsset,
3925
- 50_000_000n,
3926
- 20_000_000n,
3927
- ),
3928
- );
3929
-
3930
- const initialUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
3931
- addAssets(acc, utxo.assets),
3932
- )(await context.lucid.utxosAt(context.users.user.address));
3933
-
3934
- // Order to redeem.
3935
- await runAndAwaitTx(
3936
- context.lucid,
3937
- createStableswapOrder(
3938
- context.assetConfigs[0].iassetTokenNameAscii,
3939
- EXAMPLE_TOKEN_1,
3940
- 10_050_251n,
3941
- false,
3942
- stableswapPool.datum,
3943
- context.systemParams,
3944
- context.lucid,
3945
- ),
3946
- );
3947
-
3948
- const stableswapOrders = await findStableswapOrders(
3949
- context.lucid,
3950
- context.systemParams.validatorHashes.stableswapHash,
3951
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
3952
- EXAMPLE_TOKEN_1,
3953
- );
3954
-
3955
- await createUtxoAtTreasury(
3956
- mkLovelacesOf(2_000_000n),
3957
- context.systemParams,
3958
- context,
3959
- );
3960
-
3961
- const treasuryUtxo = await findRandomTreasuryUtxoWithOnlyAda(
3962
- context.lucid,
3963
- context.systemParams,
3964
- );
3965
-
3966
- const [__, treasuryValChange] = await getValueChangeAtAddressAfterAction(
3967
- context.lucid,
3968
- mkTreasuryAddr(context.lucid, context.systemParams),
3969
- async () =>
3970
- runAndAwaitTx(
3971
- context.lucid,
3972
- batchProcessStableswapOrders(
3973
- stableswapOrders.map((order) => order.utxo),
3974
- stableswapPool.utxo,
3975
- treasuryUtxo,
3976
- context.systemParams,
3977
- context.lucid,
3978
- ),
3979
- ),
3980
- );
3981
-
3982
- ///////////////////////////////////
3983
- // Checks after last transaction //
3984
- ///////////////////////////////////
3985
-
3986
- stableswapPool = await findStableswapPool(
3987
- context.lucid,
3988
- context.systemParams.validatorHashes.cdpHash,
3989
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
3990
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
3991
- EXAMPLE_TOKEN_1,
3992
- );
3993
-
3994
- const finalAdminValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
3995
- addAssets(acc, utxo.assets),
3996
- )(await context.lucid.utxosAt(context.users.admin.address));
3997
-
3998
- const finalUserValue = A.reduce<UTxO, Assets>({}, (acc, utxo) =>
3999
- addAssets(acc, utxo.assets),
4000
- )(await context.lucid.utxosAt(context.users.user.address));
4001
-
4002
- const adminValueDiff = addAssets(
4003
- finalAdminValue,
4004
- negateAssets(initialAdminValue),
4005
- );
4006
-
4007
- const userValueDiff = addAssets(
4008
- finalUserValue,
4009
- negateAssets(initialUserValue),
4010
- );
4011
-
4012
- const iassetAc = {
4013
- currencySymbol: fromHex(
4014
- context.systemParams.stableswapParams.iassetSymbol.unCurrencySymbol,
4015
- ),
4016
- tokenName: stableswapOrders[0].datum.iasset,
4017
- };
4018
-
4019
- assert(
4020
- assetClassValueOf(treasuryValChange, iassetAc) == 50_000n + 50_251n,
4021
- 'Unexpected iAsset value received by the treasury',
4022
- );
4023
-
4024
- assert(
4025
- assetClassValueOf(stableswapPool.utxo.assets, EXAMPLE_TOKEN_1) == 0n,
4026
- 'Unexpected value held by stableswap pool',
4027
- );
4028
-
4029
- assert(
4030
- assetClassValueOf(adminValueDiff, iassetAc) == 10_000_000n - 50_000n &&
4031
- assetClassValueOf(adminValueDiff, EXAMPLE_TOKEN_1) == -10_000_000n,
4032
- 'Unexpected value received by minting order owner',
4033
- );
4034
-
4035
- assert(
4036
- assetClassValueOf(userValueDiff, iassetAc) == -10_050_251n &&
4037
- assetClassValueOf(userValueDiff, EXAMPLE_TOKEN_1) == 10_000_000n,
4038
- 'Unexpected value received by redeeming order owner',
4039
- );
4040
- });
4041
-
4042
- test<IndigoTestContext>('Stableswap - Update fees from fee manager', async (context: IndigoTestContext) => {
4043
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
4044
-
4045
- await runCreateStableswapPool(
4046
- context.assetConfigs[0].iassetTokenNameAscii,
4047
- EXAMPLE_TOKEN_1,
4048
- context,
4049
- );
4050
-
4051
- let stableswapPool: { utxo: UTxO; datum: StableswapPoolContent } =
4052
- await findStableswapPool(
4053
- context.lucid,
4054
- context.systemParams.validatorHashes.cdpHash,
4055
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
4056
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
4057
- EXAMPLE_TOKEN_1,
4058
- );
4059
-
4060
- const feeTxHash = await runAndAwaitTxBuilder(
4061
- context.lucid,
4062
- context.lucid.newTx().pay.ToAddress(
4063
- credentialToAddress(context.lucid.config().network!, {
4064
- hash: context.systemParams.validatorHashes.stableswapHash,
4065
- type: 'Script',
4066
- }),
4067
- mkLovelacesOf(2_000_000n),
4068
- ),
4069
- );
4070
-
4071
- assert(
4072
- stableswapPool.datum.mintingFeeRatio.numerator === 5n &&
4073
- stableswapPool.datum.mintingFeeRatio.denominator === 1_000n,
4074
- 'Unexpected minting fee percentage prior to update',
4075
- );
4076
-
4077
- assert(
4078
- stableswapPool.datum.redemptionFeeRatio.numerator === 5n &&
4079
- stableswapPool.datum.redemptionFeeRatio.denominator === 1_000n,
4080
- 'Unexpected redemption fee percentage prior to update',
4081
- );
4082
-
4083
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
4084
-
4085
- await benchmarkAndAwaitTx(
4086
- 'Stableswap - Update fees',
4087
- await updateStableswapPoolFees(
4088
- stableswapPool.utxo,
4089
- { txHash: feeTxHash, outputIndex: 0 },
4090
- { numerator: 1n, denominator: 100n },
4091
- { numerator: 1n, denominator: 100n },
4092
- context.systemParams,
4093
- context.lucid,
4094
- ),
4095
- context.lucid,
4096
- context.emulator,
4097
- );
4098
-
4099
- ///////////////////////////////////
4100
- // Checks after last transaction //
4101
- ///////////////////////////////////
4102
-
4103
- stableswapPool = await findStableswapPool(
4104
- context.lucid,
4105
- context.systemParams.validatorHashes.cdpHash,
4106
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
4107
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
4108
- EXAMPLE_TOKEN_1,
4109
- );
4110
-
4111
- assert(
4112
- stableswapPool.datum.mintingFeeRatio.numerator === 1n &&
4113
- stableswapPool.datum.mintingFeeRatio.denominator === 100n,
4114
- 'Unexpected minting fee percentage',
4115
- );
4116
-
4117
- assert(
4118
- stableswapPool.datum.mintingFeeRatio.numerator === 1n &&
4119
- stableswapPool.datum.mintingFeeRatio.denominator === 100n,
4120
- 'Unexpected redemption fee percentage',
4121
- );
4122
- });
4123
-
4124
- test<IndigoTestContext>('Stableswap - Update fees from fee manager - fails with large minting fee', async (context: IndigoTestContext) => {
4125
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
4126
-
4127
- await runCreateStableswapPool(
4128
- context.assetConfigs[0].iassetTokenNameAscii,
4129
- EXAMPLE_TOKEN_1,
4130
- context,
4131
- );
4132
-
4133
- const stableswapPool: { utxo: UTxO; datum: StableswapPoolContent } =
4134
- await findStableswapPool(
4135
- context.lucid,
4136
- context.systemParams.validatorHashes.cdpHash,
4137
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
4138
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
4139
- EXAMPLE_TOKEN_1,
4140
- );
4141
-
4142
- const feeTxHash = await runAndAwaitTxBuilder(
4143
- context.lucid,
4144
- context.lucid.newTx().pay.ToAddress(
4145
- credentialToAddress(context.lucid.config().network!, {
4146
- hash: context.systemParams.validatorHashes.stableswapHash,
4147
- type: 'Script',
4148
- }),
4149
- mkLovelacesOf(2_000_000n),
4150
- ),
4151
- );
4152
-
4153
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
4154
-
4155
- await expectScriptFailure(
4156
- 'Minting fee ratio is between [0%, 100%]',
4157
- updateStableswapPoolFees(
4158
- stableswapPool.utxo,
4159
- { txHash: feeTxHash, outputIndex: 0 },
4160
- { numerator: 1_005n, denominator: 10n },
4161
- { numerator: 1n, denominator: 100n },
4162
- context.systemParams,
4163
- context.lucid,
4164
- ),
4165
- );
4166
- });
4167
-
4168
- test<IndigoTestContext>('Stableswap - Update fees from fee manager - fails with large redemption fee', async (context: IndigoTestContext) => {
4169
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
4170
-
4171
- await runCreateStableswapPool(
4172
- context.assetConfigs[0].iassetTokenNameAscii,
4173
- EXAMPLE_TOKEN_1,
4174
- context,
4175
- );
4176
-
4177
- const stableswapPool: { utxo: UTxO; datum: StableswapPoolContent } =
4178
- await findStableswapPool(
4179
- context.lucid,
4180
- context.systemParams.validatorHashes.cdpHash,
4181
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
4182
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
4183
- EXAMPLE_TOKEN_1,
4184
- );
4185
-
4186
- const feeTxHash = await runAndAwaitTxBuilder(
4187
- context.lucid,
4188
- context.lucid.newTx().pay.ToAddress(
4189
- credentialToAddress(context.lucid.config().network!, {
4190
- hash: context.systemParams.validatorHashes.stableswapHash,
4191
- type: 'Script',
4192
- }),
4193
- mkLovelacesOf(2_000_000n),
4194
- ),
4195
- );
4196
-
4197
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
4198
-
4199
- await expectScriptFailure(
4200
- 'Redemption fee ratio is between [0%, 100%]',
4201
- updateStableswapPoolFees(
4202
- stableswapPool.utxo,
4203
- { txHash: feeTxHash, outputIndex: 0 },
4204
- { numerator: 1n, denominator: 100n },
4205
- { numerator: 1_005n, denominator: 10n },
4206
- context.systemParams,
4207
- context.lucid,
4208
- ),
4209
- );
4210
- });
4211
-
4212
- test<IndigoTestContext>('Stableswap - Process a two-step order, ex. USDC -> iUSD -> USDC', async (context: IndigoTestContext) => {
4213
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
4214
-
4215
- await runCreateStableswapPool(
4216
- context.assetConfigs[0].iassetTokenNameAscii,
4217
- EXAMPLE_TOKEN_1,
4218
- context,
4219
- );
4220
-
4221
- let stableswapPool = await findStableswapPool(
4222
- context.lucid,
4223
- context.systemParams.validatorHashes.cdpHash,
4224
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
4225
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
4226
- EXAMPLE_TOKEN_1,
4227
- );
4228
-
4229
- context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
4230
- const userAddress = await context.lucid.wallet().address();
4231
- const pkh = paymentCredentialOf(userAddress);
4232
-
4233
- // Create order to mint iAsset, forwarding to a stableswap order to redeem the iAsset.
4234
- await runAndAwaitTx(
4235
- context.lucid,
4236
- createStableswapOrder(
4237
- context.assetConfigs[0].iassetTokenNameAscii,
4238
- EXAMPLE_TOKEN_1,
4239
- 10_000_000n,
4240
- true,
4241
- stableswapPool.datum,
4242
- context.systemParams,
4243
- context.lucid,
4244
- createScriptAddress(
4245
- context.lucid.config().network!,
4246
- context.systemParams.validatorHashes.stableswapHash,
4247
- ),
4248
- Data.fromCBORHex(
4249
- serialiseStableswapOrderDatum({
4250
- iasset: fromHex(
4251
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
4252
- ),
4253
- collateralAsset: EXAMPLE_TOKEN_1,
4254
- owner: fromHex(pkh.hash),
4255
- destination: addressFromBech32(userAddress),
4256
- destinationInlineDatum: null,
4257
- maxExecutionFee: BASE_MAX_EXECUTION_FEE,
4258
- maxFeeRatio: stableswapPool.datum.mintingFeeRatio,
4259
- }),
4260
- ),
4261
- BASE_MAX_EXECUTION_FEE,
4262
- 1_000_000n,
4263
- ),
4264
- );
4265
-
4266
- let stableswapOrder = await findSingleStableswapOrder(
4267
- context.lucid,
4268
- context.systemParams.validatorHashes.stableswapHash,
4269
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
4270
- EXAMPLE_TOKEN_1,
4271
- );
4272
-
4273
- await createUtxoAtTreasury(
4274
- mkLovelacesOf(2_000_000n),
4275
- context.systemParams,
4276
- context,
4277
- );
4278
-
4279
- let treasuryUtxo = await findRandomTreasuryUtxoWithOnlyAda(
4280
- context.lucid,
4281
- context.systemParams,
4282
- );
4283
-
4284
- await runAndAwaitTx(
4285
- context.lucid,
4286
- batchProcessStableswapOrders(
4287
- [stableswapOrder.utxo],
4288
- stableswapPool.utxo,
4289
- treasuryUtxo,
4290
- context.systemParams,
4291
- context.lucid,
4292
- ),
4293
- );
4294
-
4295
- // Redeem part of the collateral asset previously supplied to the pool.
4296
- stableswapOrder = await findSingleStableswapOrder(
4297
- context.lucid,
4298
- context.systemParams.validatorHashes.stableswapHash,
4299
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
4300
- EXAMPLE_TOKEN_1,
4301
- );
4302
-
4303
- stableswapPool = await findStableswapPool(
4304
- context.lucid,
4305
- context.systemParams.validatorHashes.cdpHash,
4306
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
4307
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
4308
- EXAMPLE_TOKEN_1,
4309
- );
4310
-
4311
- await createUtxoAtTreasury(
4312
- mkLovelacesOf(2_000_000n),
4313
- context.systemParams,
4314
- context,
4315
- );
4316
-
4317
- treasuryUtxo = await findRandomTreasuryUtxoWithOnlyAda(
4318
- context.lucid,
4319
- context.systemParams,
4320
- );
4321
-
4322
- await runAndAwaitTx(
4323
- context.lucid,
4324
- batchProcessStableswapOrders(
4325
- [stableswapOrder.utxo],
4326
- stableswapPool.utxo,
4327
- treasuryUtxo,
4328
- context.systemParams,
4329
- context.lucid,
4330
- ),
4331
- );
4332
- });
4333
-
4334
- test<IndigoTestContext>('Stableswap - Batcher tries to steal more than the max execution fee', async (context: IndigoTestContext) => {
4335
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
4336
-
4337
- await runCreateStableswapPool(
4338
- context.assetConfigs[0].iassetTokenNameAscii,
4339
- EXAMPLE_TOKEN_1,
4340
- context,
4341
- );
4342
-
4343
- const stableswapPool = await findStableswapPool(
4344
- context.lucid,
4345
- context.systemParams.validatorHashes.cdpHash,
4346
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
4347
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
4348
- EXAMPLE_TOKEN_1,
4349
- );
4350
-
4351
- context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
4352
-
4353
- // Create order to mint iAsset.
4354
- await runAndAwaitTx(
4355
- context.lucid,
4356
- createStableswapOrder(
4357
- context.assetConfigs[0].iassetTokenNameAscii,
4358
- EXAMPLE_TOKEN_1,
4359
- 10_000_000n,
4360
- true,
4361
- stableswapPool.datum,
4362
- context.systemParams,
4363
- context.lucid,
4364
- undefined,
4365
- undefined,
4366
- BASE_MAX_EXECUTION_FEE,
4367
- 10_000_000n,
4368
- ),
4369
- );
4370
-
4371
- const stableswapOrder = await findSingleStableswapOrder(
4372
- context.lucid,
4373
- context.systemParams.validatorHashes.stableswapHash,
4374
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
4375
- EXAMPLE_TOKEN_1,
4376
- );
4377
-
4378
- await createUtxoAtTreasury(
4379
- mkLovelacesOf(2_000_000n),
4380
- context.systemParams,
4381
- context,
4382
- );
4383
-
4384
- const treasuryUtxo = await findRandomTreasuryUtxoWithOnlyAda(
4385
- context.lucid,
4386
- context.systemParams,
4387
- );
4388
-
4389
- await expectScriptFailure(
4390
- 'Minted amount wrongly sent to order destination',
4391
- mutatedBatchProcessStableswapOrders(
4392
- [stableswapOrder.utxo],
4393
- stableswapPool.utxo,
4394
- treasuryUtxo,
4395
- context.systemParams,
4396
- context.lucid,
4397
- {
4398
- type: 'exceed-max-execution-fee',
4399
- maxExecutionFee: BASE_MAX_EXECUTION_FEE + 1_000_000n,
4400
- },
4401
- ),
4402
- );
4403
- });
4404
-
4405
- test<IndigoTestContext>('Stableswap - Pool exceeds max fee percentage', async (context: IndigoTestContext) => {
4406
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
4407
-
4408
- await runCreateStableswapPool(
4409
- context.assetConfigs[0].iassetTokenNameAscii,
4410
- EXAMPLE_TOKEN_1,
4411
- context,
4412
- );
4413
-
4414
- const stableswapPool = await findStableswapPool(
4415
- context.lucid,
4416
- context.systemParams.validatorHashes.cdpHash,
4417
- fromSystemParamsAsset(context.systemParams.stableswapParams.cdpToken),
4418
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
4419
- EXAMPLE_TOKEN_1,
4420
- );
4421
-
4422
- context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
4423
-
4424
- // Create order to mint iAsset, though with a 0% max fee percentage.
4425
- await runAndAwaitTx(
4426
- context.lucid,
4427
- createStableswapOrder(
4428
- context.assetConfigs[0].iassetTokenNameAscii,
4429
- EXAMPLE_TOKEN_1,
4430
- 10_000_000n,
4431
- true,
4432
- stableswapPool.datum,
4433
- context.systemParams,
4434
- context.lucid,
4435
- undefined,
4436
- undefined,
4437
- BASE_MAX_EXECUTION_FEE,
4438
- 0n,
4439
- rationalFromInt(0n),
4440
- ),
4441
- );
4442
-
4443
- const stableswapOrder = await findSingleStableswapOrder(
4444
- context.lucid,
4445
- context.systemParams.validatorHashes.stableswapHash,
4446
- fromText(context.assetConfigs[0].iassetTokenNameAscii),
4447
- EXAMPLE_TOKEN_1,
4448
- );
4449
-
4450
- await createUtxoAtTreasury(
4451
- mkLovelacesOf(2_000_000n),
4452
- context.systemParams,
4453
- context,
4454
- );
4455
-
4456
- const treasuryUtxo = await findRandomTreasuryUtxoWithOnlyAda(
4457
- context.lucid,
4458
- context.systemParams,
4459
- );
4460
-
4461
- await expectScriptFailure(
4462
- 'Pool minting fee exceeds order max fee ratio',
4463
- batchProcessStableswapOrders(
4464
- [stableswapOrder.utxo],
4465
- stableswapPool.utxo,
4466
- treasuryUtxo,
4467
- context.systemParams,
4468
- context.lucid,
4469
- ),
4470
- );
4471
- });