@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,3677 +0,0 @@
1
- import { assert, beforeEach, describe, expect, test } from 'vitest';
2
- import {
3
- Emulator,
4
- EmulatorAccount,
5
- fromHex,
6
- fromText,
7
- generateEmulatorAccount,
8
- Lucid,
9
- paymentCredentialOf,
10
- addAssets,
11
- } from '@lucid-evolution/lucid';
12
- import {
13
- adjustRob,
14
- cancelRob,
15
- claimRob,
16
- openRob,
17
- } from '../../src/contracts/rob/transactions';
18
- import { findAllRobs, findSingleRob } from './rob-queries';
19
- import { addrDetails } from '../../src/utils/lucid-utils';
20
- import {
21
- IndigoTestContext,
22
- LucidContext,
23
- repeat,
24
- runAndAwaitTx,
25
- runAndAwaitTxBuilder,
26
- } from '../test-helpers';
27
- import {
28
- createProposal,
29
- fromSystemParamsAsset,
30
- MIN_ROB_COLLATERAL_AMT,
31
- robAmtToSpend,
32
- robCollateralAmtToSpend,
33
- } from '../../src';
34
- import { strictEqual } from 'assert';
35
- import {
36
- adaAssetClass,
37
- AssetClass,
38
- assetClassValueOf,
39
- lovelacesAmt,
40
- mkAssetsOf,
41
- mkLovelacesOf,
42
- } from '@3rd-eye-labs/cardano-offchain-common';
43
- import {
44
- iusdInitialAssetCfg,
45
- mkBaseCollateralAsset,
46
- } from '../mock/assets-mock';
47
- import { init } from '../endpoints/initialize';
48
- import {
49
- findAllNecessaryOrefs,
50
- findOwnCdpNew,
51
- findPriceOracleFromCollateralAsset,
52
- } from '../cdp/cdp-queries';
53
- import {
54
- redeemWithCdpAdjust,
55
- redeemWithCdpClose,
56
- redeemWithCdpCreate,
57
- testRedeemRob,
58
- } from './transactions-mutated';
59
- import { expectScriptFailure, expectValue } from '../utils/asserts';
60
- import { findGov } from '../gov/governance-queries';
61
- import { findCollateralAsset } from '../queries/iasset-queries';
62
- import { processSuccessfulProposal } from '../gov/actions';
63
- import { runOpenCdp } from '../cdp/actions';
64
- import {
65
- runFeedPriceToOracle,
66
- waitForOracleExpiration,
67
- } from '../price-oracle/actions';
68
- import { runRedeemRob } from './actions';
69
- import { calculateFeeFromRatio } from '../../src/utils/indigo-helpers';
70
- import { findRandomCdpCreator as findRandomCdpCreatorNew } from '../../src/contracts/cdp-creator/queries';
71
- import {
72
- findCollateralAsset as findCollateralAssetNew,
73
- findIAsset as findIAssetNew,
74
- } from '../../src/contracts/iasset/queries';
75
- import { benchmarkAndAwaitTx } from '../utils/benchmark-utils';
76
- import { sendValueTo, totalValueAtAddress } from '../utils';
77
- import { MAINNET_PROTOCOL_PARAMETERS } from '../indigo-test-helpers';
78
- import {
79
- Rational,
80
- rationalDiv,
81
- rationalFloor,
82
- rationalFromInt,
83
- rationalMul,
84
- } from '../../src/types/rational';
85
-
86
- type MyContext = LucidContext<{
87
- admin: EmulatorAccount;
88
- user1: EmulatorAccount;
89
- user2: EmulatorAccount;
90
- }>;
91
-
92
- const collateralAssetA: AssetClass = {
93
- currencySymbol: fromHex(
94
- // random generated
95
- 'cc072059ae741791b7b9c23d9baea6a0b0d764dec617ce7e027a8dea',
96
- ),
97
- tokenName: fromHex(fromText('A')),
98
- };
99
-
100
- describe('ROB', () => {
101
- beforeEach<MyContext>(async (context: MyContext) => {
102
- context.users = {
103
- admin: generateEmulatorAccount(
104
- addAssets(
105
- mkLovelacesOf(100_000_000_000_000n),
106
- mkAssetsOf(collateralAssetA, 10_000_000_000_000n),
107
- ),
108
- ),
109
- user1: generateEmulatorAccount(
110
- addAssets(
111
- mkLovelacesOf(1_000_000_000_000n),
112
- mkAssetsOf(collateralAssetA, 10_000_000_000_000n),
113
- ),
114
- ),
115
- user2: generateEmulatorAccount(
116
- addAssets(
117
- mkLovelacesOf(1_000_000_000_000n),
118
- mkAssetsOf(collateralAssetA, 10_000_000_000_000n),
119
- ),
120
- ),
121
- };
122
-
123
- context.emulator = new Emulator(
124
- Object.values(context.users),
125
- MAINNET_PROTOCOL_PARAMETERS,
126
- );
127
- context.lucid = await Lucid(context.emulator, 'Custom');
128
- });
129
-
130
- describe('Composite Txs', () => {
131
- describe('redeem with CDP Adjust', () => {
132
- test<MyContext>('ROB buy orders redeem with CDP deposit and mint (ADA case)', async (context: MyContext) => {
133
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
134
-
135
- const [sysParams, [iusdAssetInfo]] = await init(context.lucid, [
136
- iusdInitialAssetCfg(0n),
137
- ]);
138
-
139
- const robs_count = 8; // Adjusted for Pyth updates
140
-
141
- await repeat(robs_count, async () => {
142
- await runAndAwaitTx(
143
- context.lucid,
144
- openRob(
145
- iusdAssetInfo.iassetTokenNameAscii,
146
- 20_000_000n,
147
- {
148
- BuyIAssetOrder: {
149
- collateralAsset: adaAssetClass,
150
- maxPrice: rationalFromInt(1n),
151
- },
152
- },
153
- context.lucid,
154
- sysParams,
155
- ),
156
- );
157
- });
158
-
159
- context.lucid.selectWallet.fromSeed(context.users.user1.seedPhrase);
160
-
161
- await runAndAwaitTx(
162
- context.lucid,
163
- runOpenCdp(
164
- context,
165
- sysParams,
166
- iusdAssetInfo.iassetTokenNameAscii,
167
- adaAssetClass,
168
- 100_000_000n,
169
- 500_000n,
170
- ),
171
- );
172
-
173
- const orefs = await findAllNecessaryOrefs(
174
- context.lucid,
175
- sysParams,
176
- iusdAssetInfo.iassetTokenNameAscii,
177
- adaAssetClass,
178
- );
179
-
180
- const SINGLE_REDEMPTION_AMT = 1_000_000n;
181
-
182
- const priceOracleUtxo = await findPriceOracleFromCollateralAsset(
183
- context.lucid,
184
- orefs.collateralAsset,
185
- );
186
-
187
- await benchmarkAndAwaitTx(
188
- `ROB composite - ${robs_count} buy orders redeem with CDP deposit and mint`,
189
- await redeemWithCdpAdjust(
190
- (
191
- await findAllRobs(
192
- context.lucid,
193
- sysParams,
194
- iusdAssetInfo.iassetTokenNameAscii,
195
- )
196
- ).map((rob) => [rob.utxo, SINGLE_REDEMPTION_AMT]),
197
- 5n,
198
- BigInt(robs_count) * SINGLE_REDEMPTION_AMT,
199
- (await findOwnCdpNew(context.lucid, sysParams)).utxo,
200
- orefs.iasset.utxo,
201
- orefs.collateralAsset.utxo,
202
- priceOracleUtxo!,
203
- orefs.interestOracleUtxo,
204
- orefs.treasuryUtxo,
205
- orefs.interestCollectorUtxo,
206
-
207
- context.lucid,
208
- sysParams,
209
- ),
210
- context.lucid,
211
- context.emulator,
212
- );
213
- });
214
-
215
- test<MyContext>('ROB buy orders redeem with CDP deposit and mint (non ADA case)', async (context: MyContext) => {
216
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
217
-
218
- const [sysParams, [iusdAssetInfo]] = await init(context.lucid, [
219
- {
220
- ...iusdInitialAssetCfg(),
221
- collateralAssets: [mkBaseCollateralAsset(collateralAssetA, 0n)],
222
- },
223
- ]);
224
-
225
- const robs_count = 7; // Adjusted for Pyth updates
226
-
227
- await repeat(robs_count, async () => {
228
- await runAndAwaitTx(
229
- context.lucid,
230
- openRob(
231
- iusdAssetInfo.iassetTokenNameAscii,
232
- 20_000_000n,
233
- {
234
- BuyIAssetOrder: {
235
- collateralAsset: collateralAssetA,
236
- maxPrice: rationalFromInt(1n),
237
- },
238
- },
239
- context.lucid,
240
- sysParams,
241
- ),
242
- );
243
- });
244
-
245
- context.lucid.selectWallet.fromSeed(context.users.user1.seedPhrase);
246
-
247
- const allCollateralInWallet = assetClassValueOf(
248
- await totalValueAtAddress(context.lucid, context.users.user1.address),
249
- collateralAssetA,
250
- );
251
-
252
- await runAndAwaitTx(
253
- context.lucid,
254
- runOpenCdp(
255
- context,
256
- sysParams,
257
- iusdAssetInfo.iassetTokenNameAscii,
258
- collateralAssetA,
259
- allCollateralInWallet,
260
- 500_000n,
261
- ),
262
- );
263
-
264
- const orefs = await findAllNecessaryOrefs(
265
- context.lucid,
266
- sysParams,
267
- iusdAssetInfo.iassetTokenNameAscii,
268
- collateralAssetA,
269
- );
270
-
271
- const SINGLE_PAYOUT_IASSET_AMT = 1_000_000n;
272
-
273
- const collateralAdjustment =
274
- BigInt(robs_count) *
275
- (SINGLE_PAYOUT_IASSET_AMT -
276
- calculateFeeFromRatio(
277
- (
278
- await findIAssetNew(
279
- context.lucid,
280
- sysParams,
281
- fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
282
- )
283
- ).datum.redemptionReimbursementRatio,
284
- SINGLE_PAYOUT_IASSET_AMT,
285
- ));
286
-
287
- const priceOracleUtxo = await findPriceOracleFromCollateralAsset(
288
- context.lucid,
289
- orefs.collateralAsset,
290
- );
291
-
292
- await benchmarkAndAwaitTx(
293
- `ROB composite - ${robs_count} buy orders redeem with CDP deposit and mint (non ADA case)`,
294
- await redeemWithCdpAdjust(
295
- (
296
- await findAllRobs(
297
- context.lucid,
298
- sysParams,
299
- iusdAssetInfo.iassetTokenNameAscii,
300
- )
301
- ).map((rob) => [rob.utxo, SINGLE_PAYOUT_IASSET_AMT]),
302
- // Since there's no more collateral in wallet (because all used as collateral before), this must be coming from redemptions.
303
- collateralAdjustment,
304
- BigInt(robs_count) * SINGLE_PAYOUT_IASSET_AMT,
305
- (await findOwnCdpNew(context.lucid, sysParams)).utxo,
306
- orefs.iasset.utxo,
307
- orefs.collateralAsset.utxo,
308
- priceOracleUtxo!,
309
- orefs.interestOracleUtxo,
310
- orefs.treasuryUtxo,
311
- orefs.interestCollectorUtxo,
312
-
313
- context.lucid,
314
- sysParams,
315
- ),
316
- context.lucid,
317
- context.emulator,
318
- );
319
-
320
- const res = await findOwnCdpNew(context.lucid, sysParams);
321
-
322
- expect(
323
- assetClassValueOf(res.utxo.assets, collateralAssetA),
324
- 'Expected different CDP collateral',
325
- ).toEqual(allCollateralInWallet + collateralAdjustment);
326
- });
327
-
328
- test<MyContext>('ROB sell orders redeem with CDP deposit and burn (ADA case)', async (context: MyContext) => {
329
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
330
-
331
- const [sysParams, [iusdAssetInfo]] = await init(context.lucid, [
332
- iusdInitialAssetCfg(0n),
333
- ]);
334
-
335
- const robs_count = 8;
336
- const ROB_DEPOSIT = 20_000_000n;
337
-
338
- await runAndAwaitTx(
339
- context.lucid,
340
- runOpenCdp(
341
- context,
342
- sysParams,
343
- iusdAssetInfo.iassetTokenNameAscii,
344
- adaAssetClass,
345
- 1_000_000_000n,
346
- ROB_DEPOSIT * BigInt(robs_count) +
347
- // Should cover the minting fee
348
- 1_000_000n,
349
- ),
350
- );
351
-
352
- await repeat(robs_count, async () => {
353
- await runAndAwaitTx(
354
- context.lucid,
355
- openRob(
356
- iusdAssetInfo.iassetTokenNameAscii,
357
- ROB_DEPOSIT,
358
- {
359
- SellIAssetOrder: {
360
- allowedCollateralAssets: [
361
- [adaAssetClass, rationalFromInt(1n)],
362
- ],
363
- },
364
- },
365
- context.lucid,
366
- sysParams,
367
- ),
368
- );
369
- });
370
-
371
- context.lucid.selectWallet.fromSeed(context.users.user1.seedPhrase);
372
-
373
- const INITIAL_MINT = 20_000_000n;
374
-
375
- await runAndAwaitTx(
376
- context.lucid,
377
- runOpenCdp(
378
- context,
379
- sysParams,
380
- iusdAssetInfo.iassetTokenNameAscii,
381
- adaAssetClass,
382
- 100_000_000n,
383
- INITIAL_MINT,
384
- ),
385
- );
386
-
387
- const orefs = await findAllNecessaryOrefs(
388
- context.lucid,
389
- sysParams,
390
- iusdAssetInfo.iassetTokenNameAscii,
391
- adaAssetClass,
392
- );
393
-
394
- const SINGLE_REDEMPTION_AMT = 1_000_000n;
395
-
396
- const priceOracleUtxo = await findPriceOracleFromCollateralAsset(
397
- context.lucid,
398
- orefs.collateralAsset,
399
- );
400
-
401
- await benchmarkAndAwaitTx(
402
- `ROB composite - ${robs_count} sell orders redeem with CDP deposit and burn`,
403
- await redeemWithCdpAdjust(
404
- (
405
- await findAllRobs(
406
- context.lucid,
407
- sysParams,
408
- iusdAssetInfo.iassetTokenNameAscii,
409
- )
410
- ).map((rob) => [rob.utxo, SINGLE_REDEMPTION_AMT]),
411
- 5n,
412
- -BigInt(robs_count) * SINGLE_REDEMPTION_AMT,
413
- (await findOwnCdpNew(context.lucid, sysParams)).utxo,
414
- orefs.iasset.utxo,
415
- orefs.collateralAsset.utxo,
416
- priceOracleUtxo!,
417
- orefs.interestOracleUtxo,
418
- orefs.treasuryUtxo,
419
- orefs.interestCollectorUtxo,
420
-
421
- context.lucid,
422
- sysParams,
423
- ),
424
- context.lucid,
425
- context.emulator,
426
- );
427
-
428
- const ownCdp = await findOwnCdpNew(context.lucid, sysParams);
429
-
430
- expect(ownCdp.datum.mintedAmt, 'unexpected minted amt').toEqual(
431
- INITIAL_MINT - BigInt(robs_count) * SINGLE_REDEMPTION_AMT,
432
- );
433
- });
434
-
435
- test<MyContext>('ROB sell orders redeem with CDP withdraw and burn (non ADA case)', async (context: MyContext) => {
436
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
437
-
438
- const [sysParams, [iusdAssetInfo]] = await init(context.lucid, [
439
- {
440
- ...iusdInitialAssetCfg(),
441
- collateralAssets: [mkBaseCollateralAsset(collateralAssetA, 0n)],
442
- },
443
- ]);
444
-
445
- const robs_count = 7; // TODO: Verify against Pyth feeds
446
- const ROB_DEPOSIT = 20_000_000n;
447
-
448
- await runAndAwaitTx(
449
- context.lucid,
450
- runOpenCdp(
451
- context,
452
- sysParams,
453
- iusdAssetInfo.iassetTokenNameAscii,
454
- collateralAssetA,
455
- 1_000_000_000n,
456
- ROB_DEPOSIT * BigInt(robs_count) +
457
- // Should cover the minting fee
458
- 1_000_000n,
459
- ),
460
- );
461
-
462
- await repeat(robs_count, async () => {
463
- await runAndAwaitTx(
464
- context.lucid,
465
- openRob(
466
- iusdAssetInfo.iassetTokenNameAscii,
467
- ROB_DEPOSIT,
468
- {
469
- SellIAssetOrder: {
470
- allowedCollateralAssets: [
471
- [collateralAssetA, rationalFromInt(1n)],
472
- ],
473
- },
474
- },
475
- context.lucid,
476
- sysParams,
477
- ),
478
- );
479
- });
480
-
481
- context.lucid.selectWallet.fromSeed(context.users.user1.seedPhrase);
482
-
483
- const allCollateralInWallet = assetClassValueOf(
484
- await totalValueAtAddress(context.lucid, context.users.user1.address),
485
- collateralAssetA,
486
- );
487
-
488
- const INITIAL_MINT = 20_000_000n;
489
-
490
- await runAndAwaitTx(
491
- context.lucid,
492
- runOpenCdp(
493
- context,
494
- sysParams,
495
- iusdAssetInfo.iassetTokenNameAscii,
496
- collateralAssetA,
497
- allCollateralInWallet,
498
- INITIAL_MINT,
499
- ),
500
- );
501
-
502
- const orefs = await findAllNecessaryOrefs(
503
- context.lucid,
504
- sysParams,
505
- iusdAssetInfo.iassetTokenNameAscii,
506
- collateralAssetA,
507
- );
508
-
509
- const SINGLE_REDEMPTION_AMT = 1_000_000n;
510
- const reimbursementFee = calculateFeeFromRatio(
511
- orefs.iasset.datum.redemptionReimbursementRatio,
512
- SINGLE_REDEMPTION_AMT,
513
- );
514
-
515
- const priceOracleUtxo = await findPriceOracleFromCollateralAsset(
516
- context.lucid,
517
- orefs.collateralAsset,
518
- );
519
-
520
- await benchmarkAndAwaitTx(
521
- `ROB composite - ${robs_count} sell orders redeem with CDP withdraw and burn (non ADA case)`,
522
- await redeemWithCdpAdjust(
523
- (
524
- await findAllRobs(
525
- context.lucid,
526
- sysParams,
527
- iusdAssetInfo.iassetTokenNameAscii,
528
- )
529
- ).map((rob) => [rob.utxo, SINGLE_REDEMPTION_AMT]),
530
- // Withdrawing the amount to pay for redemptions
531
- -BigInt(robs_count) * (SINGLE_REDEMPTION_AMT + reimbursementFee),
532
- // redeeming iassets, and using them to burn
533
- -BigInt(robs_count) * SINGLE_REDEMPTION_AMT,
534
- (await findOwnCdpNew(context.lucid, sysParams)).utxo,
535
- orefs.iasset.utxo,
536
- orefs.collateralAsset.utxo,
537
- priceOracleUtxo!,
538
- orefs.interestOracleUtxo,
539
- orefs.treasuryUtxo,
540
- orefs.interestCollectorUtxo,
541
-
542
- context.lucid,
543
- sysParams,
544
- ),
545
- context.lucid,
546
- context.emulator,
547
- );
548
-
549
- const ownCdp = await findOwnCdpNew(context.lucid, sysParams);
550
-
551
- expect(ownCdp.datum.mintedAmt, 'unexpected minted amt').toEqual(
552
- INITIAL_MINT - BigInt(robs_count) * SINGLE_REDEMPTION_AMT,
553
- );
554
- expect(
555
- assetClassValueOf(ownCdp.utxo.assets, collateralAssetA),
556
- 'unexpected collateral amt',
557
- ).toEqual(
558
- allCollateralInWallet -
559
- BigInt(robs_count) * (SINGLE_REDEMPTION_AMT + reimbursementFee),
560
- );
561
- });
562
- });
563
-
564
- describe('redeem with CDP close', () => {
565
- test<MyContext>('ROB sell orders redeem with CDP close (ADA case)', async (context: MyContext) => {
566
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
567
-
568
- const [sysParams, [iusdAssetInfo]] = await init(context.lucid, [
569
- iusdInitialAssetCfg(0n),
570
- ]);
571
-
572
- const robs_count = 5;
573
- const ROB_DEPOSIT = 20_000_000n;
574
-
575
- await runAndAwaitTx(
576
- context.lucid,
577
- runOpenCdp(
578
- context,
579
- sysParams,
580
- iusdAssetInfo.iassetTokenNameAscii,
581
- adaAssetClass,
582
- 1_000_000_000n,
583
- ROB_DEPOSIT * BigInt(robs_count) +
584
- // Should cover the minting fee
585
- 1_000_000n,
586
- ),
587
- );
588
-
589
- await repeat(robs_count, async () => {
590
- await runAndAwaitTx(
591
- context.lucid,
592
- openRob(
593
- iusdAssetInfo.iassetTokenNameAscii,
594
- ROB_DEPOSIT,
595
- {
596
- SellIAssetOrder: {
597
- allowedCollateralAssets: [
598
- [adaAssetClass, rationalFromInt(1n)],
599
- ],
600
- },
601
- },
602
- context.lucid,
603
- sysParams,
604
- ),
605
- );
606
- });
607
-
608
- context.lucid.selectWallet.fromSeed(context.users.user1.seedPhrase);
609
-
610
- const SINGLE_PAYOUT_COLLATERAL_AMT = 1_000_000n;
611
-
612
- const mintAmt =
613
- BigInt(robs_count) *
614
- (SINGLE_PAYOUT_COLLATERAL_AMT -
615
- calculateFeeFromRatio(
616
- (
617
- await findIAssetNew(
618
- context.lucid,
619
- sysParams,
620
- fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
621
- )
622
- ).datum.redemptionReimbursementRatio,
623
- SINGLE_PAYOUT_COLLATERAL_AMT,
624
- ));
625
-
626
- await runAndAwaitTx(
627
- context.lucid,
628
- runOpenCdp(
629
- context,
630
- sysParams,
631
- iusdAssetInfo.iassetTokenNameAscii,
632
- adaAssetClass,
633
- 100_000_000n,
634
- mintAmt,
635
- ),
636
- );
637
-
638
- const iassetAc = {
639
- currencySymbol: fromHex(
640
- sysParams.cdpParams.cdpAssetSymbol.unCurrencySymbol,
641
- ),
642
- tokenName: fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
643
- };
644
-
645
- await sendValueTo(
646
- context.users.user2.address,
647
- mkAssetsOf(
648
- iassetAc,
649
- assetClassValueOf(
650
- await totalValueAtAddress(
651
- context.lucid,
652
- context.users.user1.address,
653
- ),
654
- iassetAc,
655
- ),
656
- ),
657
- context.lucid,
658
- );
659
-
660
- const orefs = await findAllNecessaryOrefs(
661
- context.lucid,
662
- sysParams,
663
- iusdAssetInfo.iassetTokenNameAscii,
664
- adaAssetClass,
665
- );
666
-
667
- const priceOracleUtxo = await findPriceOracleFromCollateralAsset(
668
- context.lucid,
669
- orefs.collateralAsset,
670
- );
671
-
672
- await benchmarkAndAwaitTx(
673
- `ROB composite - ${robs_count} sell orders redeem with CDP close (ADA case)`,
674
- await redeemWithCdpClose(
675
- (
676
- await findAllRobs(
677
- context.lucid,
678
- sysParams,
679
- iusdAssetInfo.iassetTokenNameAscii,
680
- )
681
- ).map((rob) => [rob.utxo, SINGLE_PAYOUT_COLLATERAL_AMT]),
682
- (await findOwnCdpNew(context.lucid, sysParams)).utxo,
683
- orefs.iasset.utxo,
684
- orefs.collateralAsset.utxo,
685
- priceOracleUtxo!,
686
- orefs.interestOracleUtxo,
687
- orefs.interestCollectorUtxo,
688
- sysParams,
689
- context.lucid,
690
- ),
691
- context.lucid,
692
- context.emulator,
693
- );
694
- });
695
-
696
- test<MyContext>('ROB sell orders redeem with CDP close (non ADA case)', async (context: MyContext) => {
697
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
698
-
699
- const [sysParams, [iusdAssetInfo]] = await init(context.lucid, [
700
- {
701
- ...iusdInitialAssetCfg(),
702
- collateralAssets: [mkBaseCollateralAsset(collateralAssetA, 0n)],
703
- },
704
- ]);
705
-
706
- const robs_count = 4;
707
- const ROB_DEPOSIT = 20_000_000n;
708
-
709
- await runAndAwaitTx(
710
- context.lucid,
711
- runOpenCdp(
712
- context,
713
- sysParams,
714
- iusdAssetInfo.iassetTokenNameAscii,
715
- collateralAssetA,
716
- 1_000_000_000n,
717
- ROB_DEPOSIT * BigInt(robs_count) +
718
- // Should cover the minting fee
719
- 1_000_000n,
720
- ),
721
- );
722
-
723
- await repeat(robs_count, async () => {
724
- await runAndAwaitTx(
725
- context.lucid,
726
- openRob(
727
- iusdAssetInfo.iassetTokenNameAscii,
728
- ROB_DEPOSIT,
729
- {
730
- SellIAssetOrder: {
731
- allowedCollateralAssets: [
732
- [collateralAssetA, rationalFromInt(1n)],
733
- ],
734
- },
735
- },
736
- context.lucid,
737
- sysParams,
738
- ),
739
- );
740
- });
741
-
742
- context.lucid.selectWallet.fromSeed(context.users.user1.seedPhrase);
743
-
744
- const SINGLE_PAYOUT_COLLATERAL_AMT = 1_000_000n;
745
-
746
- const mintAmt =
747
- BigInt(robs_count) *
748
- (SINGLE_PAYOUT_COLLATERAL_AMT -
749
- calculateFeeFromRatio(
750
- (
751
- await findIAssetNew(
752
- context.lucid,
753
- sysParams,
754
- fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
755
- )
756
- ).datum.redemptionReimbursementRatio,
757
- SINGLE_PAYOUT_COLLATERAL_AMT,
758
- ));
759
-
760
- await runAndAwaitTx(
761
- context.lucid,
762
- runOpenCdp(
763
- context,
764
- sysParams,
765
- iusdAssetInfo.iassetTokenNameAscii,
766
- collateralAssetA,
767
- 100_000_000n,
768
- mintAmt,
769
- ),
770
- );
771
-
772
- const iassetAc = {
773
- currencySymbol: fromHex(
774
- sysParams.cdpParams.cdpAssetSymbol.unCurrencySymbol,
775
- ),
776
- tokenName: fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
777
- };
778
-
779
- await sendValueTo(
780
- context.users.user2.address,
781
- mkAssetsOf(
782
- iassetAc,
783
- assetClassValueOf(
784
- await totalValueAtAddress(
785
- context.lucid,
786
- context.users.user1.address,
787
- ),
788
- iassetAc,
789
- ),
790
- ),
791
- context.lucid,
792
- );
793
-
794
- const orefs = await findAllNecessaryOrefs(
795
- context.lucid,
796
- sysParams,
797
- iusdAssetInfo.iassetTokenNameAscii,
798
- collateralAssetA,
799
- );
800
-
801
- const priceOracleUtxo = await findPriceOracleFromCollateralAsset(
802
- context.lucid,
803
- orefs.collateralAsset,
804
- );
805
-
806
- await benchmarkAndAwaitTx(
807
- `ROB composite - ${robs_count} sell orders redeem with CDP close (non ADA case)`,
808
- await redeemWithCdpClose(
809
- (
810
- await findAllRobs(
811
- context.lucid,
812
- sysParams,
813
- iusdAssetInfo.iassetTokenNameAscii,
814
- )
815
- ).map((rob) => [rob.utxo, SINGLE_PAYOUT_COLLATERAL_AMT]),
816
- (await findOwnCdpNew(context.lucid, sysParams)).utxo,
817
- orefs.iasset.utxo,
818
- orefs.collateralAsset.utxo,
819
- priceOracleUtxo!,
820
- orefs.interestOracleUtxo,
821
- orefs.interestCollectorUtxo,
822
- sysParams,
823
- context.lucid,
824
- ),
825
- context.lucid,
826
- context.emulator,
827
- );
828
- });
829
- });
830
-
831
- describe('redeem with CDP create', () => {
832
- test<MyContext>('ROB buy orders redeem with CDP create (ADA case)', async (context: MyContext) => {
833
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
834
-
835
- const [sysParams, [iusdAssetInfo]] = await init(context.lucid, [
836
- iusdInitialAssetCfg(0n),
837
- ]);
838
-
839
- const robs_count = 4;
840
-
841
- await repeat(robs_count, async () => {
842
- await runAndAwaitTx(
843
- context.lucid,
844
- openRob(
845
- iusdAssetInfo.iassetTokenNameAscii,
846
- 20_000_000n,
847
- {
848
- BuyIAssetOrder: {
849
- collateralAsset: adaAssetClass,
850
- maxPrice: rationalFromInt(1n),
851
- },
852
- },
853
- context.lucid,
854
- sysParams,
855
- ),
856
- );
857
- });
858
-
859
- context.lucid.selectWallet.fromSeed(context.users.user1.seedPhrase);
860
-
861
- const orefs = await findAllNecessaryOrefs(
862
- context.lucid,
863
- sysParams,
864
- iusdAssetInfo.iassetTokenNameAscii,
865
- adaAssetClass,
866
- );
867
-
868
- const SINGLE_PAYOUT_IASSET_AMT = 1_000_000n;
869
-
870
- const mintedAmt =
871
- BigInt(robs_count) * SINGLE_PAYOUT_IASSET_AMT +
872
- // This is extra that minting fee is paid from and user keeps what we validate after this Tx.
873
- SINGLE_PAYOUT_IASSET_AMT;
874
-
875
- const priceOracleUtxo = await findPriceOracleFromCollateralAsset(
876
- context.lucid,
877
- orefs.collateralAsset,
878
- );
879
-
880
- await benchmarkAndAwaitTx(
881
- `ROB composite - ${robs_count} buy orders redeem with CDP create (ADA case)`,
882
- await redeemWithCdpCreate(
883
- (
884
- await findAllRobs(
885
- context.lucid,
886
- sysParams,
887
- iusdAssetInfo.iassetTokenNameAscii,
888
- )
889
- ).map((rob) => [rob.utxo, SINGLE_PAYOUT_IASSET_AMT]),
890
- 100_000_000n,
891
- // everything that gets minted is sent to ROB
892
- mintedAmt,
893
- sysParams,
894
- await findRandomCdpCreatorNew(context.lucid, sysParams),
895
- orefs.iasset.utxo,
896
- orefs.collateralAsset.utxo,
897
- priceOracleUtxo!,
898
- orefs.interestOracleUtxo,
899
- orefs.treasuryUtxo,
900
- context.lucid,
901
- ),
902
- context.lucid,
903
- context.emulator,
904
- );
905
-
906
- expect(
907
- assetClassValueOf(
908
- await totalValueAtAddress(
909
- context.lucid,
910
- context.users.user1.address,
911
- ),
912
- {
913
- currencySymbol: fromHex(
914
- sysParams.robParams.iassetPolicyId.unCurrencySymbol,
915
- ),
916
- tokenName: fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
917
- },
918
- ),
919
- 'Unexpected iassets owned by user',
920
- ).toEqual(
921
- SINGLE_PAYOUT_IASSET_AMT -
922
- calculateFeeFromRatio(
923
- (
924
- await findIAssetNew(
925
- context.lucid,
926
- sysParams,
927
- fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
928
- )
929
- ).datum.debtMintingFeeRatio,
930
- mintedAmt,
931
- ),
932
- );
933
- });
934
-
935
- test<MyContext>('ROB buy orders redeem with CDP create (non ADA case)', async (context: MyContext) => {
936
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
937
-
938
- const [sysParams, [iusdAssetInfo]] = await init(context.lucid, [
939
- {
940
- ...iusdInitialAssetCfg(),
941
- collateralAssets: [mkBaseCollateralAsset(collateralAssetA, 0n)],
942
- },
943
- ]);
944
-
945
- const robs_count = 3;
946
-
947
- await repeat(robs_count, async () => {
948
- await runAndAwaitTx(
949
- context.lucid,
950
- openRob(
951
- iusdAssetInfo.iassetTokenNameAscii,
952
- 20_000_000n,
953
- {
954
- BuyIAssetOrder: {
955
- collateralAsset: collateralAssetA,
956
- maxPrice: rationalFromInt(1n),
957
- },
958
- },
959
- context.lucid,
960
- sysParams,
961
- ),
962
- );
963
- });
964
-
965
- context.lucid.selectWallet.fromSeed(context.users.user1.seedPhrase);
966
-
967
- const orefs = await findAllNecessaryOrefs(
968
- context.lucid,
969
- sysParams,
970
- iusdAssetInfo.iassetTokenNameAscii,
971
- collateralAssetA,
972
- );
973
-
974
- const SINGLE_PAYOUT_IASSET_AMT = 1_000_000n;
975
-
976
- const mintedAmt =
977
- BigInt(robs_count) * SINGLE_PAYOUT_IASSET_AMT +
978
- // This is extra that minting fee is paid from and user keeps what we validate after this Tx.
979
- SINGLE_PAYOUT_IASSET_AMT;
980
- const priceOracleUtxo = await findPriceOracleFromCollateralAsset(
981
- context.lucid,
982
- orefs.collateralAsset,
983
- );
984
- await benchmarkAndAwaitTx(
985
- `ROB composite - ${robs_count} buy orders redeem with CDP create (non ADA case)`,
986
- await redeemWithCdpCreate(
987
- (
988
- await findAllRobs(
989
- context.lucid,
990
- sysParams,
991
- iusdAssetInfo.iassetTokenNameAscii,
992
- )
993
- ).map((rob) => [rob.utxo, SINGLE_PAYOUT_IASSET_AMT]),
994
- // use all as collateral
995
- assetClassValueOf(
996
- await totalValueAtAddress(
997
- context.lucid,
998
- context.users.user1.address,
999
- ),
1000
- collateralAssetA,
1001
- ),
1002
- // everything that gets minted is sent to ROB
1003
- mintedAmt,
1004
- sysParams,
1005
- await findRandomCdpCreatorNew(context.lucid, sysParams),
1006
- orefs.iasset.utxo,
1007
- orefs.collateralAsset.utxo,
1008
- priceOracleUtxo!,
1009
- orefs.interestOracleUtxo,
1010
- orefs.treasuryUtxo,
1011
- context.lucid,
1012
- ),
1013
- context.lucid,
1014
- context.emulator,
1015
- );
1016
-
1017
- const userVal = await totalValueAtAddress(
1018
- context.lucid,
1019
- context.users.user1.address,
1020
- );
1021
- expect(
1022
- assetClassValueOf(userVal, {
1023
- currencySymbol: fromHex(
1024
- sysParams.robParams.iassetPolicyId.unCurrencySymbol,
1025
- ),
1026
- tokenName: fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
1027
- }),
1028
- 'Unexpected iassets owned by user',
1029
- ).toEqual(
1030
- SINGLE_PAYOUT_IASSET_AMT -
1031
- calculateFeeFromRatio(
1032
- (
1033
- await findIAssetNew(
1034
- context.lucid,
1035
- sysParams,
1036
- fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
1037
- )
1038
- ).datum.debtMintingFeeRatio,
1039
- mintedAmt,
1040
- ),
1041
- );
1042
-
1043
- // Since everything was used as collateral, user owns only the amount after redemption.
1044
- expect(
1045
- assetClassValueOf(userVal, collateralAssetA),
1046
- 'Unexpected collateral owned by user',
1047
- ).toEqual(
1048
- BigInt(robs_count) *
1049
- (SINGLE_PAYOUT_IASSET_AMT -
1050
- calculateFeeFromRatio(
1051
- (
1052
- await findIAssetNew(
1053
- context.lucid,
1054
- sysParams,
1055
- fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
1056
- )
1057
- ).datum.redemptionReimbursementRatio,
1058
- SINGLE_PAYOUT_IASSET_AMT,
1059
- )),
1060
- );
1061
- });
1062
- });
1063
- });
1064
-
1065
- test<MyContext>('adjust order type BUY positive and negative', async (context: MyContext) => {
1066
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
1067
-
1068
- const [sysParams, [iusdAssetInfo]] = await init(context.lucid, [
1069
- iusdInitialAssetCfg(),
1070
- ]);
1071
-
1072
- const [ownPkh, _] = await addrDetails(context.lucid);
1073
-
1074
- await runAndAwaitTx(
1075
- context.lucid,
1076
- openRob(
1077
- iusdAssetInfo.iassetTokenNameAscii,
1078
- 20_000_000n,
1079
- {
1080
- BuyIAssetOrder: {
1081
- collateralAsset: adaAssetClass,
1082
- maxPrice: rationalFromInt(1n),
1083
- },
1084
- },
1085
- context.lucid,
1086
- sysParams,
1087
- ),
1088
- );
1089
-
1090
- {
1091
- const robBefore = await findSingleRob(
1092
- context,
1093
- sysParams,
1094
- iusdAssetInfo.iassetTokenNameAscii,
1095
- ownPkh,
1096
- );
1097
-
1098
- const amtToSpendBefore = robCollateralAmtToSpend(
1099
- robBefore.utxo.assets,
1100
- robBefore.datum.orderType,
1101
- );
1102
-
1103
- await runAndAwaitTx(
1104
- context.lucid,
1105
- adjustRob(
1106
- context.lucid,
1107
- robBefore.utxo,
1108
- -1_000_000n,
1109
- undefined,
1110
- sysParams,
1111
- ),
1112
- );
1113
-
1114
- const adjustedUtxo1 = await findSingleRob(
1115
- context,
1116
- sysParams,
1117
- iusdAssetInfo.iassetTokenNameAscii,
1118
- ownPkh,
1119
- );
1120
-
1121
- const amtToSpendAfter = robCollateralAmtToSpend(
1122
- adjustedUtxo1.utxo.assets,
1123
- adjustedUtxo1.datum.orderType,
1124
- );
1125
-
1126
- assert(amtToSpendBefore - amtToSpendAfter === 1_000_000n);
1127
-
1128
- expect(
1129
- lovelacesAmt(adjustedUtxo1.utxo.assets) >= amtToSpendAfter,
1130
- 'Lovelaces to spend has to be smaller than actual lovelaces in UTXO',
1131
- ).toBeTruthy();
1132
- }
1133
-
1134
- {
1135
- const robBefore = await findSingleRob(
1136
- context,
1137
- sysParams,
1138
- iusdAssetInfo.iassetTokenNameAscii,
1139
- ownPkh,
1140
- );
1141
-
1142
- const amtToSpendBefore = robCollateralAmtToSpend(
1143
- robBefore.utxo.assets,
1144
- robBefore.datum.orderType,
1145
- );
1146
-
1147
- await runAndAwaitTx(
1148
- context.lucid,
1149
- adjustRob(
1150
- context.lucid,
1151
- robBefore.utxo,
1152
- 5_000_000n,
1153
- undefined,
1154
- sysParams,
1155
- ),
1156
- );
1157
-
1158
- const adjustedUtxo2 = await findSingleRob(
1159
- context,
1160
- sysParams,
1161
- iusdAssetInfo.iassetTokenNameAscii,
1162
- ownPkh,
1163
- );
1164
-
1165
- const amtToSpendAfter = robCollateralAmtToSpend(
1166
- adjustedUtxo2.utxo.assets,
1167
- adjustedUtxo2.datum.orderType,
1168
- );
1169
-
1170
- strictEqual(amtToSpendAfter - amtToSpendBefore, 5_000_000n);
1171
-
1172
- expect(
1173
- lovelacesAmt(adjustedUtxo2.utxo.assets) >= amtToSpendAfter,
1174
- 'Lovelaces to spend has to be smaller than actual lovelaces in UTXO',
1175
- ).toBeTruthy();
1176
- }
1177
- });
1178
-
1179
- test<MyContext>('adjust order type SELL positive and negative', async (context: MyContext) => {
1180
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
1181
-
1182
- const [sysParams, [iusdAssetInfo]] = await init(context.lucid, [
1183
- iusdInitialAssetCfg(),
1184
- ]);
1185
-
1186
- const [ownPkh, _] = await addrDetails(context.lucid);
1187
-
1188
- await runAndAwaitTx(
1189
- context.lucid,
1190
- runOpenCdp(
1191
- context,
1192
- sysParams,
1193
- iusdAssetInfo.iassetTokenNameAscii,
1194
- adaAssetClass,
1195
- 100_000_000n,
1196
- 30_000_000n,
1197
- ),
1198
- );
1199
-
1200
- await runAndAwaitTx(
1201
- context.lucid,
1202
- openRob(
1203
- iusdAssetInfo.iassetTokenNameAscii,
1204
- 20_000_000n,
1205
- {
1206
- SellIAssetOrder: {
1207
- allowedCollateralAssets: [[adaAssetClass, rationalFromInt(1n)]],
1208
- },
1209
- },
1210
- context.lucid,
1211
- sysParams,
1212
- ),
1213
- );
1214
-
1215
- await runAndAwaitTx(
1216
- context.lucid,
1217
- findSingleRob(
1218
- context,
1219
- sysParams,
1220
- iusdAssetInfo.iassetTokenNameAscii,
1221
- ownPkh,
1222
- ).then((rob) =>
1223
- adjustRob(context.lucid, rob.utxo, -1_000_000n, undefined, sysParams),
1224
- ),
1225
- );
1226
-
1227
- const adjustedUtxo1 = await findSingleRob(
1228
- context,
1229
- sysParams,
1230
- iusdAssetInfo.iassetTokenNameAscii,
1231
- ownPkh,
1232
- );
1233
-
1234
- const iassetAc: AssetClass = {
1235
- currencySymbol: fromHex(
1236
- sysParams.robParams.iassetPolicyId.unCurrencySymbol,
1237
- ),
1238
- tokenName: fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
1239
- };
1240
-
1241
- assert(
1242
- robAmtToSpend(adjustedUtxo1.utxo.assets, adjustedUtxo1.datum.orderType, {
1243
- currencySymbol: fromHex(
1244
- sysParams.cdpParams.cdpAssetSymbol.unCurrencySymbol,
1245
- ),
1246
- tokenName: adjustedUtxo1.datum.iasset,
1247
- }) ===
1248
- 20_000_000n - 1_000_000n,
1249
- );
1250
-
1251
- expect(
1252
- assetClassValueOf(adjustedUtxo1.utxo.assets, iassetAc) ===
1253
- robAmtToSpend(
1254
- adjustedUtxo1.utxo.assets,
1255
- adjustedUtxo1.datum.orderType,
1256
- {
1257
- currencySymbol: fromHex(
1258
- sysParams.cdpParams.cdpAssetSymbol.unCurrencySymbol,
1259
- ),
1260
- tokenName: adjustedUtxo1.datum.iasset,
1261
- },
1262
- ),
1263
- 'IAssets to spend has to equal iassets in UTXO',
1264
- ).toBeTruthy();
1265
-
1266
- await runAndAwaitTx(
1267
- context.lucid,
1268
- adjustRob(
1269
- context.lucid,
1270
- adjustedUtxo1.utxo,
1271
- 5_000_000n,
1272
- undefined,
1273
- sysParams,
1274
- ),
1275
- );
1276
-
1277
- const adjustedUtxo2 = await findSingleRob(
1278
- context,
1279
- sysParams,
1280
- iusdAssetInfo.iassetTokenNameAscii,
1281
- ownPkh,
1282
- );
1283
-
1284
- const expectedResultAdaAmt = 20_000_000n - 1_000_000n + 5_000_000n;
1285
-
1286
- strictEqual(
1287
- robAmtToSpend(adjustedUtxo2.utxo.assets, adjustedUtxo2.datum.orderType, {
1288
- currencySymbol: fromHex(
1289
- sysParams.cdpParams.cdpAssetSymbol.unCurrencySymbol,
1290
- ),
1291
- tokenName: adjustedUtxo2.datum.iasset,
1292
- }),
1293
- expectedResultAdaAmt,
1294
- );
1295
-
1296
- expect(
1297
- assetClassValueOf(adjustedUtxo2.utxo.assets, iassetAc) >=
1298
- robAmtToSpend(
1299
- adjustedUtxo2.utxo.assets,
1300
- adjustedUtxo2.datum.orderType,
1301
- {
1302
- currencySymbol: fromHex(
1303
- sysParams.cdpParams.cdpAssetSymbol.unCurrencySymbol,
1304
- ),
1305
- tokenName: adjustedUtxo2.datum.iasset,
1306
- },
1307
- ),
1308
- 'IAssets to spend has to equal iassets in UTXO',
1309
- ).toBeTruthy();
1310
- });
1311
-
1312
- test<MyContext>('claim from BUY order type after a redemption', async (context: MyContext) => {
1313
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
1314
-
1315
- const [sysParams, [iusdAssetInfo]] = await init(context.lucid, [
1316
- iusdInitialAssetCfg(),
1317
- ]);
1318
-
1319
- const [ownPkh, _] = await addrDetails(context.lucid);
1320
-
1321
- await runAndAwaitTx(
1322
- context.lucid,
1323
- runOpenCdp(
1324
- context,
1325
- sysParams,
1326
- iusdAssetInfo.iassetTokenNameAscii,
1327
- adaAssetClass,
1328
- 100_000_000n,
1329
- 30_000_000n,
1330
- ),
1331
- );
1332
-
1333
- await runAndAwaitTx(
1334
- context.lucid,
1335
- openRob(
1336
- iusdAssetInfo.iassetTokenNameAscii,
1337
- 20_000_000n,
1338
- {
1339
- BuyIAssetOrder: {
1340
- collateralAsset: adaAssetClass,
1341
- maxPrice: rationalFromInt(1n),
1342
- },
1343
- },
1344
- context.lucid,
1345
- sysParams,
1346
- ),
1347
- );
1348
-
1349
- const robUtxo = await findSingleRob(
1350
- context,
1351
- sysParams,
1352
- iusdAssetInfo.iassetTokenNameAscii,
1353
- ownPkh,
1354
- );
1355
-
1356
- const iassetAc: AssetClass = {
1357
- currencySymbol: fromHex(
1358
- sysParams.robParams.iassetPolicyId.unCurrencySymbol,
1359
- ),
1360
- tokenName: fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
1361
- };
1362
-
1363
- expect(
1364
- assetClassValueOf(robUtxo.utxo.assets, iassetAc),
1365
- 'ROB should have no iassets before redemption',
1366
- ).toBe(0n);
1367
-
1368
- const redemptionIAssetAmt = 11_000_000n;
1369
-
1370
- const amtToSpendBefore = robCollateralAmtToSpend(
1371
- robUtxo.utxo.assets,
1372
- robUtxo.datum.orderType,
1373
- );
1374
-
1375
- await runAndAwaitTx(
1376
- context.lucid,
1377
- runRedeemRob(
1378
- context,
1379
- sysParams,
1380
- [[robUtxo, redemptionIAssetAmt]],
1381
- iusdAssetInfo.iassetTokenNameAscii,
1382
- adaAssetClass,
1383
- ),
1384
- );
1385
-
1386
- const redeemedRob = await findSingleRob(
1387
- context,
1388
- sysParams,
1389
- iusdAssetInfo.iassetTokenNameAscii,
1390
- ownPkh,
1391
- );
1392
-
1393
- expect(
1394
- assetClassValueOf(redeemedRob.utxo.assets, iassetAc),
1395
- 'ROB has wrong number of iassets after redemption',
1396
- ).toEqual(redemptionIAssetAmt);
1397
-
1398
- expect(
1399
- amtToSpendBefore -
1400
- robCollateralAmtToSpend(
1401
- redeemedRob.utxo.assets,
1402
- redeemedRob.datum.orderType,
1403
- ),
1404
- 'ROB has wrong number redeemed',
1405
- ).toEqual(
1406
- // Since price is 1
1407
- redemptionIAssetAmt -
1408
- calculateFeeFromRatio(
1409
- (
1410
- await findIAssetNew(
1411
- context.lucid,
1412
- sysParams,
1413
- fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
1414
- )
1415
- ).datum.redemptionReimbursementRatio,
1416
- redemptionIAssetAmt,
1417
- ),
1418
- );
1419
-
1420
- await runAndAwaitTx(
1421
- context.lucid,
1422
- claimRob(context.lucid, redeemedRob.utxo, sysParams),
1423
- );
1424
-
1425
- const claimedRob = await findSingleRob(
1426
- context,
1427
- sysParams,
1428
- iusdAssetInfo.iassetTokenNameAscii,
1429
- ownPkh,
1430
- );
1431
-
1432
- expect(
1433
- assetClassValueOf(claimedRob.utxo.assets, iassetAc),
1434
- 'ROB has to have 0 redemption assets after claim',
1435
- ).toBe(0n);
1436
- });
1437
-
1438
- test<MyContext>('claim from BUY order type after a redemption when price is NOT 1:1', async (context: MyContext) => {
1439
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
1440
-
1441
- const [sysParams, [iusdAssetInfo]] = await init(context.lucid, [
1442
- iusdInitialAssetCfg(),
1443
- ]);
1444
-
1445
- const [ownPkh, _] = await addrDetails(context.lucid);
1446
-
1447
- await runAndAwaitTx(
1448
- context.lucid,
1449
- runOpenCdp(
1450
- context,
1451
- sysParams,
1452
- iusdAssetInfo.iassetTokenNameAscii,
1453
- adaAssetClass,
1454
- 100_000_000n,
1455
- 30_000_000n,
1456
- ),
1457
- );
1458
-
1459
- const initialDeposit = 20_000_000n;
1460
-
1461
- await runAndAwaitTx(
1462
- context.lucid,
1463
- openRob(
1464
- iusdAssetInfo.iassetTokenNameAscii,
1465
- initialDeposit,
1466
- {
1467
- BuyIAssetOrder: {
1468
- collateralAsset: adaAssetClass,
1469
- maxPrice: rationalFromInt(1n),
1470
- },
1471
- },
1472
- context.lucid,
1473
- sysParams,
1474
- ),
1475
- );
1476
-
1477
- const robUtxo = await findSingleRob(
1478
- context,
1479
- sysParams,
1480
- iusdAssetInfo.iassetTokenNameAscii,
1481
- ownPkh,
1482
- );
1483
-
1484
- const iassetAc: AssetClass = {
1485
- currencySymbol: fromHex(
1486
- sysParams.robParams.iassetPolicyId.unCurrencySymbol,
1487
- ),
1488
- tokenName: fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
1489
- };
1490
-
1491
- expect(
1492
- assetClassValueOf(robUtxo.utxo.assets, iassetAc),
1493
- 'ROB should have no iassets before redemption',
1494
- ).toBe(0n);
1495
-
1496
- const newPrice: Rational = { numerator: 75n, denominator: 100n };
1497
- await runFeedPriceToOracle(
1498
- context,
1499
- sysParams,
1500
- iusdAssetInfo,
1501
- adaAssetClass,
1502
- newPrice,
1503
- );
1504
-
1505
- const redemptionIAssetAmt = 7_500_000n;
1506
-
1507
- await runAndAwaitTx(
1508
- context.lucid,
1509
- runRedeemRob(
1510
- context,
1511
- sysParams,
1512
- [[robUtxo, redemptionIAssetAmt]],
1513
- iusdAssetInfo.iassetTokenNameAscii,
1514
- adaAssetClass,
1515
- ),
1516
- );
1517
-
1518
- const redeemedRob = await findSingleRob(
1519
- context,
1520
- sysParams,
1521
- iusdAssetInfo.iassetTokenNameAscii,
1522
- ownPkh,
1523
- );
1524
-
1525
- const expectedRedeemedAmt = rationalFloor(
1526
- rationalMul(
1527
- rationalFromInt(
1528
- redemptionIAssetAmt -
1529
- calculateFeeFromRatio(
1530
- (
1531
- await findIAssetNew(
1532
- context.lucid,
1533
- sysParams,
1534
- fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
1535
- )
1536
- ).datum.redemptionReimbursementRatio,
1537
- redemptionIAssetAmt,
1538
- ),
1539
- ),
1540
- newPrice,
1541
- ),
1542
- );
1543
-
1544
- expect(
1545
- robCollateralAmtToSpend(
1546
- redeemedRob.utxo.assets,
1547
- redeemedRob.datum.orderType,
1548
- ),
1549
- 'Wrong amt to spend in datum',
1550
- ).toEqual(initialDeposit - expectedRedeemedAmt);
1551
-
1552
- expectValue(
1553
- redeemedRob.utxo.assets,
1554
- 'Wrong value after redemption',
1555
- ).toEqual(
1556
- addAssets(
1557
- mkAssetsOf(iassetAc, redemptionIAssetAmt),
1558
- mkLovelacesOf(
1559
- MIN_ROB_COLLATERAL_AMT + initialDeposit - expectedRedeemedAmt,
1560
- ),
1561
- ),
1562
- );
1563
-
1564
- await runAndAwaitTx(
1565
- context.lucid,
1566
- claimRob(context.lucid, redeemedRob.utxo, sysParams),
1567
- );
1568
-
1569
- const claimedRob = await findSingleRob(
1570
- context,
1571
- sysParams,
1572
- iusdAssetInfo.iassetTokenNameAscii,
1573
- ownPkh,
1574
- );
1575
-
1576
- expect(
1577
- assetClassValueOf(claimedRob.utxo.assets, iassetAc),
1578
- 'ROB has to have 0 redemption assets after claim',
1579
- ).toBe(0n);
1580
- });
1581
-
1582
- test<MyContext>('claim from SELL order type after a redemption when price is NOT 1:1', async (context: MyContext) => {
1583
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
1584
-
1585
- const [sysParams, [iusdAssetInfo]] = await init(context.lucid, [
1586
- iusdInitialAssetCfg(),
1587
- ]);
1588
-
1589
- const [ownPkh, _] = await addrDetails(context.lucid);
1590
-
1591
- await runAndAwaitTx(
1592
- context.lucid,
1593
- runOpenCdp(
1594
- context,
1595
- sysParams,
1596
- iusdAssetInfo.iassetTokenNameAscii,
1597
- adaAssetClass,
1598
- 100_000_000n,
1599
- 30_000_000n,
1600
- ),
1601
- );
1602
-
1603
- const initialDeposit = 20_000_000n;
1604
-
1605
- await runAndAwaitTx(
1606
- context.lucid,
1607
- openRob(
1608
- iusdAssetInfo.iassetTokenNameAscii,
1609
- initialDeposit,
1610
- {
1611
- SellIAssetOrder: {
1612
- allowedCollateralAssets: [[adaAssetClass, rationalFromInt(1n)]],
1613
- },
1614
- },
1615
- context.lucid,
1616
- sysParams,
1617
- ),
1618
- );
1619
-
1620
- const robUtxo = await findSingleRob(
1621
- context,
1622
- sysParams,
1623
- iusdAssetInfo.iassetTokenNameAscii,
1624
- ownPkh,
1625
- );
1626
-
1627
- const iassetAc: AssetClass = {
1628
- currencySymbol: fromHex(
1629
- sysParams.robParams.iassetPolicyId.unCurrencySymbol,
1630
- ),
1631
- tokenName: fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
1632
- };
1633
-
1634
- expectValue(
1635
- robUtxo.utxo.assets,
1636
- 'Wrong ROB value before redemption',
1637
- ).toEqual(
1638
- addAssets(
1639
- mkLovelacesOf(MIN_ROB_COLLATERAL_AMT),
1640
- mkAssetsOf(iassetAc, initialDeposit),
1641
- ),
1642
- );
1643
-
1644
- const newPrice: Rational = { numerator: 125n, denominator: 100n };
1645
- await runFeedPriceToOracle(
1646
- context,
1647
- sysParams,
1648
- iusdAssetInfo,
1649
- adaAssetClass,
1650
- newPrice,
1651
- );
1652
-
1653
- const payoutCollateralAmt = 7_500_000n;
1654
-
1655
- await runAndAwaitTx(
1656
- context.lucid,
1657
- runRedeemRob(
1658
- context,
1659
- sysParams,
1660
- [[robUtxo, payoutCollateralAmt]],
1661
- iusdAssetInfo.iassetTokenNameAscii,
1662
- adaAssetClass,
1663
- ),
1664
- );
1665
-
1666
- const redeemedRob = await findSingleRob(
1667
- context,
1668
- sysParams,
1669
- iusdAssetInfo.iassetTokenNameAscii,
1670
- ownPkh,
1671
- );
1672
-
1673
- const expectedRedemptionAmt = rationalFloor(
1674
- rationalDiv(
1675
- rationalFromInt(
1676
- payoutCollateralAmt -
1677
- calculateFeeFromRatio(
1678
- (
1679
- await findIAssetNew(
1680
- context.lucid,
1681
- sysParams,
1682
- fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
1683
- )
1684
- ).datum.redemptionReimbursementRatio,
1685
- payoutCollateralAmt,
1686
- ),
1687
- ),
1688
- newPrice,
1689
- ),
1690
- );
1691
-
1692
- expect(
1693
- robAmtToSpend(redeemedRob.utxo.assets, redeemedRob.datum.orderType, {
1694
- currencySymbol: fromHex(
1695
- sysParams.cdpParams.cdpAssetSymbol.unCurrencySymbol,
1696
- ),
1697
- tokenName: redeemedRob.datum.iasset,
1698
- }),
1699
- 'Wrong amt to spend in datum',
1700
- ).toEqual(initialDeposit - expectedRedemptionAmt);
1701
-
1702
- expectValue(
1703
- redeemedRob.utxo.assets,
1704
- 'Wrong value after redemption',
1705
- ).toEqual(
1706
- addAssets(
1707
- mkAssetsOf(adaAssetClass, MIN_ROB_COLLATERAL_AMT + payoutCollateralAmt),
1708
- mkAssetsOf(iassetAc, initialDeposit - expectedRedemptionAmt),
1709
- ),
1710
- );
1711
-
1712
- await runAndAwaitTx(
1713
- context.lucid,
1714
- claimRob(context.lucid, redeemedRob.utxo, sysParams),
1715
- );
1716
- });
1717
-
1718
- test<MyContext>('redemption of BUY order type when limit price not met fails', async (context: MyContext) => {
1719
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
1720
-
1721
- const [sysParams, [iusdAssetInfo]] = await init(context.lucid, [
1722
- iusdInitialAssetCfg(),
1723
- ]);
1724
-
1725
- const [ownPkh, _] = await addrDetails(context.lucid);
1726
-
1727
- await runAndAwaitTx(
1728
- context.lucid,
1729
- runOpenCdp(
1730
- context,
1731
- sysParams,
1732
- iusdAssetInfo.iassetTokenNameAscii,
1733
- adaAssetClass,
1734
- 100_000_000n,
1735
- 30_000_000n,
1736
- ),
1737
- );
1738
-
1739
- await runAndAwaitTx(
1740
- context.lucid,
1741
- openRob(
1742
- iusdAssetInfo.iassetTokenNameAscii,
1743
- 20_000_000n,
1744
- {
1745
- BuyIAssetOrder: {
1746
- collateralAsset: adaAssetClass,
1747
- maxPrice: { numerator: 9n, denominator: 10n },
1748
- },
1749
- },
1750
- context.lucid,
1751
- sysParams,
1752
- ),
1753
- );
1754
-
1755
- const robUtxo = await findSingleRob(
1756
- context,
1757
- sysParams,
1758
- iusdAssetInfo.iassetTokenNameAscii,
1759
- ownPkh,
1760
- );
1761
-
1762
- const iassetAc: AssetClass = {
1763
- currencySymbol: fromHex(
1764
- sysParams.robParams.iassetPolicyId.unCurrencySymbol,
1765
- ),
1766
- tokenName: fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
1767
- };
1768
-
1769
- expect(
1770
- assetClassValueOf(robUtxo.utxo.assets, iassetAc),
1771
- 'ROB should have no iassets before redemption',
1772
- ).toBe(0n);
1773
-
1774
- await expectScriptFailure(
1775
- 'Max price exceeded',
1776
- runRedeemRob(
1777
- context,
1778
- sysParams,
1779
- [[robUtxo, 11_000_000n]],
1780
- iusdAssetInfo.iassetTokenNameAscii,
1781
- adaAssetClass,
1782
- ),
1783
- );
1784
- });
1785
-
1786
- test<MyContext>('claim ADA collateral from SELL order type after a redemption', async (context: MyContext) => {
1787
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
1788
-
1789
- const [sysParams, [iusdAssetInfo]] = await init(context.lucid, [
1790
- iusdInitialAssetCfg(),
1791
- ]);
1792
-
1793
- const [ownPkh, _] = await addrDetails(context.lucid);
1794
-
1795
- await runAndAwaitTx(
1796
- context.lucid,
1797
- runOpenCdp(
1798
- context,
1799
- sysParams,
1800
- iusdAssetInfo.iassetTokenNameAscii,
1801
- adaAssetClass,
1802
- 100_000_000n,
1803
- 30_000_000n,
1804
- ),
1805
- );
1806
-
1807
- await runAndAwaitTx(
1808
- context.lucid,
1809
- openRob(
1810
- iusdAssetInfo.iassetTokenNameAscii,
1811
- 20_000_000n,
1812
- {
1813
- SellIAssetOrder: {
1814
- allowedCollateralAssets: [[adaAssetClass, rationalFromInt(1n)]],
1815
- },
1816
- },
1817
- context.lucid,
1818
- sysParams,
1819
- ),
1820
- );
1821
-
1822
- const robUtxo = await findSingleRob(
1823
- context,
1824
- sysParams,
1825
- iusdAssetInfo.iassetTokenNameAscii,
1826
- ownPkh,
1827
- );
1828
-
1829
- const iassetAc: AssetClass = {
1830
- currencySymbol: fromHex(
1831
- sysParams.robParams.iassetPolicyId.unCurrencySymbol,
1832
- ),
1833
- tokenName: fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
1834
- };
1835
-
1836
- const payoutCollateralAmt = 11_000_000n;
1837
-
1838
- await runAndAwaitTx(
1839
- context.lucid,
1840
- runRedeemRob(
1841
- context,
1842
- sysParams,
1843
- [[robUtxo, payoutCollateralAmt]],
1844
- iusdAssetInfo.iassetTokenNameAscii,
1845
- adaAssetClass,
1846
- ),
1847
- );
1848
-
1849
- const redeemedRob = await findSingleRob(
1850
- context,
1851
- sysParams,
1852
- iusdAssetInfo.iassetTokenNameAscii,
1853
- ownPkh,
1854
- );
1855
-
1856
- // Price is 1
1857
- const expectedRedemptionAmt =
1858
- payoutCollateralAmt -
1859
- calculateFeeFromRatio(
1860
- (
1861
- await findIAssetNew(
1862
- context.lucid,
1863
- sysParams,
1864
- fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
1865
- )
1866
- ).datum.redemptionReimbursementRatio,
1867
- payoutCollateralAmt,
1868
- );
1869
-
1870
- expect(
1871
- assetClassValueOf(redeemedRob.utxo.assets, iassetAc),
1872
- 'ROB has wrong number of iassets after redemption',
1873
- ).toBe(20_000_000n - expectedRedemptionAmt);
1874
-
1875
- await runAndAwaitTx(
1876
- context.lucid,
1877
- claimRob(context.lucid, redeemedRob.utxo, sysParams),
1878
- );
1879
-
1880
- const claimedRob = await findSingleRob(
1881
- context,
1882
- sysParams,
1883
- iusdAssetInfo.iassetTokenNameAscii,
1884
- ownPkh,
1885
- );
1886
-
1887
- expect(
1888
- assetClassValueOf(claimedRob.utxo.assets, adaAssetClass),
1889
- 'ROB has to have 0 redemption assets after claim',
1890
- ).toBe(MIN_ROB_COLLATERAL_AMT);
1891
- });
1892
-
1893
- test<MyContext>('redemption of SELL order type when limit price not met fails', async (context: MyContext) => {
1894
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
1895
-
1896
- const [sysParams, [iusdAssetInfo]] = await init(context.lucid, [
1897
- iusdInitialAssetCfg(),
1898
- ]);
1899
-
1900
- const [ownPkh, _] = await addrDetails(context.lucid);
1901
-
1902
- await runAndAwaitTx(
1903
- context.lucid,
1904
- runOpenCdp(
1905
- context,
1906
- sysParams,
1907
- iusdAssetInfo.iassetTokenNameAscii,
1908
- adaAssetClass,
1909
- 100_000_000n,
1910
- 30_000_000n,
1911
- ),
1912
- );
1913
-
1914
- await runAndAwaitTx(
1915
- context.lucid,
1916
- openRob(
1917
- iusdAssetInfo.iassetTokenNameAscii,
1918
- 20_000_000n,
1919
- {
1920
- SellIAssetOrder: {
1921
- allowedCollateralAssets: [
1922
- [adaAssetClass, { numerator: 11n, denominator: 10n }],
1923
- ],
1924
- },
1925
- },
1926
- context.lucid,
1927
- sysParams,
1928
- ),
1929
- );
1930
-
1931
- const robUtxo = await findSingleRob(
1932
- context,
1933
- sysParams,
1934
- iusdAssetInfo.iassetTokenNameAscii,
1935
- ownPkh,
1936
- );
1937
-
1938
- await expectScriptFailure(
1939
- 'Min price not satisfied',
1940
- runRedeemRob(
1941
- context,
1942
- sysParams,
1943
- [[robUtxo, 11_000_000n]],
1944
- iusdAssetInfo.iassetTokenNameAscii,
1945
- adaAssetClass,
1946
- ),
1947
- );
1948
- });
1949
-
1950
- test<MyContext>('claim 2 collateral assets from SELL order type after 2 redemptions', async (context: MyContext) => {
1951
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
1952
-
1953
- const [sysParams, [iusdAssetInfo]] = await init(context.lucid, [
1954
- {
1955
- ...iusdInitialAssetCfg(),
1956
- collateralAssets: [
1957
- mkBaseCollateralAsset(adaAssetClass, 0n),
1958
- mkBaseCollateralAsset(collateralAssetA, 0n),
1959
- ],
1960
- },
1961
- ]);
1962
-
1963
- const [ownPkh, _] = await addrDetails(context.lucid);
1964
-
1965
- const iassetAC: AssetClass = {
1966
- currencySymbol: fromHex(
1967
- sysParams.robParams.iassetPolicyId.unCurrencySymbol,
1968
- ),
1969
- tokenName: fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
1970
- };
1971
-
1972
- await runAndAwaitTx(
1973
- context.lucid,
1974
- runOpenCdp(
1975
- context,
1976
- sysParams,
1977
- iusdAssetInfo.iassetTokenNameAscii,
1978
- adaAssetClass,
1979
- 100_000_000n,
1980
- 30_000_000n,
1981
- ),
1982
- );
1983
-
1984
- await runAndAwaitTx(
1985
- context.lucid,
1986
- openRob(
1987
- iusdAssetInfo.iassetTokenNameAscii,
1988
- 20_000_000n,
1989
- {
1990
- SellIAssetOrder: {
1991
- allowedCollateralAssets: [
1992
- [adaAssetClass, rationalFromInt(1n)],
1993
- [collateralAssetA, rationalFromInt(1n)],
1994
- ],
1995
- },
1996
- },
1997
- context.lucid,
1998
- sysParams,
1999
- ),
2000
- );
2001
-
2002
- const payoutCollateralAmt = 2_000_000n;
2003
-
2004
- const expectedRedemptionAmt =
2005
- payoutCollateralAmt -
2006
- calculateFeeFromRatio(
2007
- (
2008
- await findIAssetNew(
2009
- context.lucid,
2010
- sysParams,
2011
- fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
2012
- )
2013
- ).datum.redemptionReimbursementRatio,
2014
- payoutCollateralAmt,
2015
- );
2016
-
2017
- /**********
2018
- * First redemption of ROB using ADA as payout
2019
- ***********/
2020
-
2021
- {
2022
- await runAndAwaitTx(
2023
- context.lucid,
2024
- runRedeemRob(
2025
- context,
2026
- sysParams,
2027
- [
2028
- [
2029
- await findSingleRob(
2030
- context,
2031
- sysParams,
2032
- iusdAssetInfo.iassetTokenNameAscii,
2033
- ownPkh,
2034
- ),
2035
- payoutCollateralAmt,
2036
- ],
2037
- ],
2038
- iusdAssetInfo.iassetTokenNameAscii,
2039
- adaAssetClass,
2040
- ),
2041
- );
2042
-
2043
- expect(
2044
- assetClassValueOf(
2045
- (
2046
- await findSingleRob(
2047
- context,
2048
- sysParams,
2049
- iusdAssetInfo.iassetTokenNameAscii,
2050
- ownPkh,
2051
- )
2052
- ).utxo.assets,
2053
- iassetAC,
2054
- ),
2055
- 'ROB has wrong number of iassets after redemption',
2056
- ).toBe(20_000_000n - expectedRedemptionAmt);
2057
- }
2058
-
2059
- /**********
2060
- * Second redemption of ROB using Collateral A as payout
2061
- ***********/
2062
-
2063
- {
2064
- await runAndAwaitTx(
2065
- context.lucid,
2066
- runRedeemRob(
2067
- context,
2068
- sysParams,
2069
- [
2070
- [
2071
- await findSingleRob(
2072
- context,
2073
- sysParams,
2074
- iusdAssetInfo.iassetTokenNameAscii,
2075
- ownPkh,
2076
- ),
2077
- payoutCollateralAmt,
2078
- ],
2079
- ],
2080
- iusdAssetInfo.iassetTokenNameAscii,
2081
- collateralAssetA,
2082
- ),
2083
- );
2084
-
2085
- expectValue(
2086
- (
2087
- await findSingleRob(
2088
- context,
2089
- sysParams,
2090
- iusdAssetInfo.iassetTokenNameAscii,
2091
- ownPkh,
2092
- )
2093
- ).utxo.assets,
2094
- 'Wrong ROB value after 2 redemptions',
2095
- ).toEqual(
2096
- addAssets(
2097
- mkLovelacesOf(MIN_ROB_COLLATERAL_AMT + payoutCollateralAmt),
2098
- mkAssetsOf(collateralAssetA, payoutCollateralAmt),
2099
- mkAssetsOf(iassetAC, 20_000_000n - 2n * expectedRedemptionAmt),
2100
- ),
2101
- );
2102
- }
2103
-
2104
- const redeemedRob = await findSingleRob(
2105
- context,
2106
- sysParams,
2107
- iusdAssetInfo.iassetTokenNameAscii,
2108
- ownPkh,
2109
- );
2110
-
2111
- await runAndAwaitTx(
2112
- context.lucid,
2113
- claimRob(context.lucid, redeemedRob.utxo, sysParams),
2114
- );
2115
-
2116
- const claimedRob = await findSingleRob(
2117
- context,
2118
- sysParams,
2119
- iusdAssetInfo.iassetTokenNameAscii,
2120
- ownPkh,
2121
- );
2122
-
2123
- expect(
2124
- assetClassValueOf(claimedRob.utxo.assets, adaAssetClass),
2125
- 'ROB has to have 0 redemption assets after claim',
2126
- ).toBe(MIN_ROB_COLLATERAL_AMT);
2127
- });
2128
-
2129
- test<MyContext>('claim using adjust after a redemption', async (context: MyContext) => {
2130
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
2131
-
2132
- const [sysParams, [iusdAssetInfo]] = await init(context.lucid, [
2133
- iusdInitialAssetCfg(),
2134
- ]);
2135
-
2136
- const [ownPkh, _] = await addrDetails(context.lucid);
2137
-
2138
- await runAndAwaitTx(
2139
- context.lucid,
2140
- runOpenCdp(
2141
- context,
2142
- sysParams,
2143
- iusdAssetInfo.iassetTokenNameAscii,
2144
- adaAssetClass,
2145
- 100_000_000n,
2146
- 30_000_000n,
2147
- ),
2148
- );
2149
-
2150
- await runAndAwaitTx(
2151
- context.lucid,
2152
- openRob(
2153
- iusdAssetInfo.iassetTokenNameAscii,
2154
- 20_000_000n,
2155
- {
2156
- BuyIAssetOrder: {
2157
- collateralAsset: adaAssetClass,
2158
- maxPrice: rationalFromInt(1n),
2159
- },
2160
- },
2161
- context.lucid,
2162
- sysParams,
2163
- ),
2164
- );
2165
-
2166
- const robUtxo = await findSingleRob(
2167
- context,
2168
- sysParams,
2169
- iusdAssetInfo.iassetTokenNameAscii,
2170
- ownPkh,
2171
- );
2172
-
2173
- const iassetAc: AssetClass = {
2174
- currencySymbol: fromHex(
2175
- sysParams.robParams.iassetPolicyId.unCurrencySymbol,
2176
- ),
2177
- tokenName: fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
2178
- };
2179
-
2180
- expect(
2181
- assetClassValueOf(robUtxo.utxo.assets, iassetAc),
2182
- 'ROB should have no iassets before redemption',
2183
- ).toBe(0n);
2184
-
2185
- const payoutIAssetAmt = 11_000_000n;
2186
-
2187
- await runAndAwaitTx(
2188
- context.lucid,
2189
- runRedeemRob(
2190
- context,
2191
- sysParams,
2192
- [[robUtxo, payoutIAssetAmt]],
2193
- iusdAssetInfo.iassetTokenNameAscii,
2194
- adaAssetClass,
2195
- ),
2196
- );
2197
-
2198
- const redeemedRob = await findSingleRob(
2199
- context,
2200
- sysParams,
2201
- iusdAssetInfo.iassetTokenNameAscii,
2202
- ownPkh,
2203
- );
2204
-
2205
- expect(
2206
- assetClassValueOf(redeemedRob.utxo.assets, iassetAc),
2207
- 'ROB has wrong number of iassets after redemption',
2208
- ).toBe(payoutIAssetAmt);
2209
-
2210
- await runAndAwaitTx(
2211
- context.lucid,
2212
- adjustRob(
2213
- context.lucid,
2214
- redeemedRob.utxo,
2215
- -1_000_000n,
2216
- undefined,
2217
- sysParams,
2218
- ),
2219
- );
2220
-
2221
- const adjustedRob = await findSingleRob(
2222
- context,
2223
- sysParams,
2224
- iusdAssetInfo.iassetTokenNameAscii,
2225
- ownPkh,
2226
- );
2227
-
2228
- expect(
2229
- assetClassValueOf(adjustedRob.utxo.assets, iassetAc),
2230
- 'ROB has to have 0 redemption assets after adjust',
2231
- ).toBe(0n);
2232
-
2233
- // Since price is 1
2234
- expect(
2235
- robCollateralAmtToSpend(
2236
- adjustedRob.utxo.assets,
2237
- adjustedRob.datum.orderType,
2238
- ),
2239
- ).toEqual(
2240
- // 20mil start, -1mil adjusted, rest redeemed
2241
- 20_000_000n -
2242
- 1_000_000n -
2243
- payoutIAssetAmt +
2244
- calculateFeeFromRatio(
2245
- (
2246
- await findIAssetNew(
2247
- context.lucid,
2248
- sysParams,
2249
- fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
2250
- )
2251
- ).datum.redemptionReimbursementRatio,
2252
- payoutIAssetAmt,
2253
- ),
2254
- );
2255
- });
2256
-
2257
- test<MyContext>('single redemption and cancel', async (context: MyContext) => {
2258
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
2259
-
2260
- const [sysParams, [iusdAssetInfo]] = await init(context.lucid, [
2261
- iusdInitialAssetCfg(),
2262
- ]);
2263
-
2264
- const [ownPkh, _] = await addrDetails(context.lucid);
2265
-
2266
- await runAndAwaitTx(
2267
- context.lucid,
2268
- runOpenCdp(
2269
- context,
2270
- sysParams,
2271
- iusdAssetInfo.iassetTokenNameAscii,
2272
- adaAssetClass,
2273
- 100_000_000n,
2274
- 30_000_000n,
2275
- ),
2276
- );
2277
-
2278
- await runAndAwaitTx(
2279
- context.lucid,
2280
- openRob(
2281
- iusdAssetInfo.iassetTokenNameAscii,
2282
- 20_000_000n,
2283
- {
2284
- BuyIAssetOrder: {
2285
- collateralAsset: adaAssetClass,
2286
- maxPrice: rationalFromInt(1n),
2287
- },
2288
- },
2289
- context.lucid,
2290
- sysParams,
2291
- ),
2292
- );
2293
-
2294
- const robUtxo = await findSingleRob(
2295
- context,
2296
- sysParams,
2297
- iusdAssetInfo.iassetTokenNameAscii,
2298
- ownPkh,
2299
- );
2300
-
2301
- const iassetAc: AssetClass = {
2302
- currencySymbol: fromHex(
2303
- sysParams.robParams.iassetPolicyId.unCurrencySymbol,
2304
- ),
2305
- tokenName: fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
2306
- };
2307
-
2308
- expect(
2309
- assetClassValueOf(robUtxo.utxo.assets, iassetAc),
2310
- 'ROB should have no iassets before redemption',
2311
- ).toBe(0n);
2312
-
2313
- const payoutIAssetAmt = 11_000_000n;
2314
-
2315
- await runAndAwaitTx(
2316
- context.lucid,
2317
- runRedeemRob(
2318
- context,
2319
- sysParams,
2320
- [[robUtxo, payoutIAssetAmt]],
2321
- iusdAssetInfo.iassetTokenNameAscii,
2322
- adaAssetClass,
2323
- ),
2324
- );
2325
-
2326
- const redeemedRob = await findSingleRob(
2327
- context,
2328
- sysParams,
2329
- iusdAssetInfo.iassetTokenNameAscii,
2330
- ownPkh,
2331
- );
2332
-
2333
- expect(
2334
- assetClassValueOf(redeemedRob.utxo.assets, iassetAc),
2335
- 'ROB has wrong number of iassets after redemption',
2336
- ).toBe(payoutIAssetAmt);
2337
-
2338
- await runAndAwaitTx(
2339
- context.lucid,
2340
- cancelRob(redeemedRob.utxo, sysParams, context.lucid),
2341
- );
2342
- });
2343
-
2344
- test<MyContext>('redeem, redeem again and cancel', async (context: MyContext) => {
2345
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
2346
-
2347
- const [sysParams, [iusdAssetInfo]] = await init(context.lucid, [
2348
- iusdInitialAssetCfg(),
2349
- ]);
2350
-
2351
- const [ownPkh, _] = await addrDetails(context.lucid);
2352
-
2353
- await runAndAwaitTx(
2354
- context.lucid,
2355
- runOpenCdp(
2356
- context,
2357
- sysParams,
2358
- iusdAssetInfo.iassetTokenNameAscii,
2359
- adaAssetClass,
2360
- 100_000_000n,
2361
- 30_000_000n,
2362
- ),
2363
- );
2364
-
2365
- await runAndAwaitTx(
2366
- context.lucid,
2367
- openRob(
2368
- iusdAssetInfo.iassetTokenNameAscii,
2369
- 40_000_000n,
2370
- {
2371
- BuyIAssetOrder: {
2372
- collateralAsset: adaAssetClass,
2373
- maxPrice: rationalFromInt(1n),
2374
- },
2375
- },
2376
- context.lucid,
2377
- sysParams,
2378
- ),
2379
- );
2380
-
2381
- const robUtxo = await findSingleRob(
2382
- context,
2383
- sysParams,
2384
- iusdAssetInfo.iassetTokenNameAscii,
2385
- ownPkh,
2386
- );
2387
-
2388
- const iassetAc: AssetClass = {
2389
- currencySymbol: fromHex(
2390
- sysParams.robParams.iassetPolicyId.unCurrencySymbol,
2391
- ),
2392
- tokenName: fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
2393
- };
2394
-
2395
- expect(
2396
- assetClassValueOf(robUtxo.utxo.assets, iassetAc),
2397
- 'ROB should have no iassets before redemption',
2398
- ).toBe(0n);
2399
-
2400
- const payoutIAssetAmt = 11_000_000n;
2401
-
2402
- await runAndAwaitTx(
2403
- context.lucid,
2404
- runRedeemRob(
2405
- context,
2406
- sysParams,
2407
- [[robUtxo, payoutIAssetAmt]],
2408
- iusdAssetInfo.iassetTokenNameAscii,
2409
- adaAssetClass,
2410
- ),
2411
- );
2412
-
2413
- const redeemedRob = await findSingleRob(
2414
- context,
2415
- sysParams,
2416
- iusdAssetInfo.iassetTokenNameAscii,
2417
- ownPkh,
2418
- );
2419
-
2420
- expect(
2421
- assetClassValueOf(redeemedRob.utxo.assets, iassetAc),
2422
- 'ROB has wrong number of iassets after redemption',
2423
- ).toBe(payoutIAssetAmt);
2424
-
2425
- await runAndAwaitTx(
2426
- context.lucid,
2427
- runRedeemRob(
2428
- context,
2429
- sysParams,
2430
- [[redeemedRob, payoutIAssetAmt]],
2431
- iusdAssetInfo.iassetTokenNameAscii,
2432
- adaAssetClass,
2433
- ),
2434
- );
2435
-
2436
- const closableRob = await findSingleRob(
2437
- context,
2438
- sysParams,
2439
- iusdAssetInfo.iassetTokenNameAscii,
2440
- ownPkh,
2441
- );
2442
-
2443
- strictEqual(
2444
- assetClassValueOf(closableRob.utxo.assets, iassetAc),
2445
- payoutIAssetAmt * 2n,
2446
- 'ROB has wrong number of iassets after 2 redemptions',
2447
- );
2448
-
2449
- await runAndAwaitTx(
2450
- context.lucid,
2451
- cancelRob(closableRob.utxo, sysParams, context.lucid),
2452
- );
2453
- });
2454
-
2455
- test<MyContext>('multi redemption buy ROBs case (2 ROBs)', async (context: MyContext) => {
2456
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
2457
-
2458
- const [sysParams, [iusdAssetInfo]] = await init(context.lucid, [
2459
- iusdInitialAssetCfg(),
2460
- ]);
2461
-
2462
- await runAndAwaitTx(
2463
- context.lucid,
2464
- runOpenCdp(
2465
- context,
2466
- sysParams,
2467
- iusdAssetInfo.iassetTokenNameAscii,
2468
- adaAssetClass,
2469
- 100_000_000n,
2470
- 30_000_000n,
2471
- ),
2472
- );
2473
-
2474
- const initialDeposit = 20_000_000n;
2475
-
2476
- await runAndAwaitTx(
2477
- context.lucid,
2478
- openRob(
2479
- iusdAssetInfo.iassetTokenNameAscii,
2480
- initialDeposit,
2481
- {
2482
- BuyIAssetOrder: {
2483
- collateralAsset: adaAssetClass,
2484
- maxPrice: rationalFromInt(1n),
2485
- },
2486
- },
2487
- context.lucid,
2488
- sysParams,
2489
- ),
2490
- );
2491
-
2492
- context.lucid.selectWallet.fromSeed(context.users.user1.seedPhrase);
2493
-
2494
- await runAndAwaitTx(
2495
- context.lucid,
2496
- openRob(
2497
- iusdAssetInfo.iassetTokenNameAscii,
2498
- initialDeposit,
2499
- {
2500
- BuyIAssetOrder: {
2501
- collateralAsset: adaAssetClass,
2502
- maxPrice: rationalFromInt(1n),
2503
- },
2504
- },
2505
- context.lucid,
2506
- sysParams,
2507
- ),
2508
- );
2509
-
2510
- const robUtxo1 = await findSingleRob(
2511
- context,
2512
- sysParams,
2513
- iusdAssetInfo.iassetTokenNameAscii,
2514
- paymentCredentialOf(context.users.admin.address),
2515
- );
2516
- const robUtxo2 = await findSingleRob(
2517
- context,
2518
- sysParams,
2519
- iusdAssetInfo.iassetTokenNameAscii,
2520
- paymentCredentialOf(context.users.user1.address),
2521
- );
2522
-
2523
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
2524
-
2525
- await runAndAwaitTx(
2526
- context.lucid,
2527
- runRedeemRob(
2528
- context,
2529
- sysParams,
2530
- [
2531
- [robUtxo1, 10_000_000n],
2532
- [robUtxo2, 11_000_000n],
2533
- ],
2534
- iusdAssetInfo.iassetTokenNameAscii,
2535
- adaAssetClass,
2536
- ),
2537
- );
2538
-
2539
- const resultRobUtxo1 = await findSingleRob(
2540
- context,
2541
- sysParams,
2542
- iusdAssetInfo.iassetTokenNameAscii,
2543
- paymentCredentialOf(context.users.admin.address),
2544
- );
2545
- const resultRobUtxo2 = await findSingleRob(
2546
- context,
2547
- sysParams,
2548
- iusdAssetInfo.iassetTokenNameAscii,
2549
- paymentCredentialOf(context.users.user1.address),
2550
- );
2551
-
2552
- const iassetAc: AssetClass = {
2553
- currencySymbol: fromHex(
2554
- sysParams.robParams.iassetPolicyId.unCurrencySymbol,
2555
- ),
2556
- tokenName: fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
2557
- };
2558
-
2559
- expectValue(resultRobUtxo1.utxo.assets, 'Wrong ROB1 value').toEqual(
2560
- addAssets(
2561
- mkLovelacesOf(
2562
- MIN_ROB_COLLATERAL_AMT +
2563
- initialDeposit -
2564
- 10_000_000n +
2565
- calculateFeeFromRatio(
2566
- (
2567
- await findIAssetNew(
2568
- context.lucid,
2569
- sysParams,
2570
- fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
2571
- )
2572
- ).datum.redemptionReimbursementRatio,
2573
- 10_000_000n,
2574
- ),
2575
- ),
2576
- mkAssetsOf(iassetAc, 10_000_000n),
2577
- ),
2578
- );
2579
- expectValue(resultRobUtxo2.utxo.assets, 'Wrong ROB2 value').toEqual(
2580
- addAssets(
2581
- mkLovelacesOf(
2582
- MIN_ROB_COLLATERAL_AMT +
2583
- initialDeposit -
2584
- 11_000_000n +
2585
- calculateFeeFromRatio(
2586
- (
2587
- await findIAssetNew(
2588
- context.lucid,
2589
- sysParams,
2590
- fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
2591
- )
2592
- ).datum.redemptionReimbursementRatio,
2593
- 11_000_000n,
2594
- ),
2595
- ),
2596
- mkAssetsOf(iassetAc, 11_000_000n),
2597
- ),
2598
- );
2599
- });
2600
-
2601
- test<MyContext>('multi redemption sell ROBs case (2 ROBs)', async (context: MyContext) => {
2602
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
2603
-
2604
- const [sysParams, [iusdAssetInfo]] = await init(context.lucid, [
2605
- iusdInitialAssetCfg(),
2606
- ]);
2607
-
2608
- const initialDeposit = 20_000_000n;
2609
-
2610
- /**********
2611
- * user 1 opens ROB
2612
- ***********/
2613
- {
2614
- context.lucid.selectWallet.fromSeed(context.users.user1.seedPhrase);
2615
-
2616
- await runAndAwaitTx(
2617
- context.lucid,
2618
- runOpenCdp(
2619
- context,
2620
- sysParams,
2621
- iusdAssetInfo.iassetTokenNameAscii,
2622
- adaAssetClass,
2623
- 100_000_000n,
2624
- 30_000_000n,
2625
- ),
2626
- );
2627
-
2628
- await runAndAwaitTx(
2629
- context.lucid,
2630
- openRob(
2631
- iusdAssetInfo.iassetTokenNameAscii,
2632
- initialDeposit,
2633
- {
2634
- SellIAssetOrder: {
2635
- allowedCollateralAssets: [[adaAssetClass, rationalFromInt(1n)]],
2636
- },
2637
- },
2638
- context.lucid,
2639
- sysParams,
2640
- ),
2641
- );
2642
- }
2643
-
2644
- /**********
2645
- * user 2 opens ROB
2646
- ***********/
2647
- {
2648
- context.lucid.selectWallet.fromSeed(context.users.user2.seedPhrase);
2649
-
2650
- await runAndAwaitTx(
2651
- context.lucid,
2652
- runOpenCdp(
2653
- context,
2654
- sysParams,
2655
- iusdAssetInfo.iassetTokenNameAscii,
2656
- adaAssetClass,
2657
- 100_000_000n,
2658
- 30_000_000n,
2659
- ),
2660
- );
2661
-
2662
- await runAndAwaitTx(
2663
- context.lucid,
2664
- openRob(
2665
- iusdAssetInfo.iassetTokenNameAscii,
2666
- initialDeposit,
2667
- {
2668
- SellIAssetOrder: {
2669
- allowedCollateralAssets: [[adaAssetClass, rationalFromInt(1n)]],
2670
- },
2671
- },
2672
- context.lucid,
2673
- sysParams,
2674
- ),
2675
- );
2676
- }
2677
-
2678
- const robUtxo1 = await findSingleRob(
2679
- context,
2680
- sysParams,
2681
- iusdAssetInfo.iassetTokenNameAscii,
2682
- paymentCredentialOf(context.users.user1.address),
2683
- );
2684
- const robUtxo2 = await findSingleRob(
2685
- context,
2686
- sysParams,
2687
- iusdAssetInfo.iassetTokenNameAscii,
2688
- paymentCredentialOf(context.users.user2.address),
2689
- );
2690
-
2691
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
2692
-
2693
- await runAndAwaitTx(
2694
- context.lucid,
2695
- runRedeemRob(
2696
- context,
2697
- sysParams,
2698
- [
2699
- [robUtxo1, 10_000_000n],
2700
- [robUtxo2, 11_000_000n],
2701
- ],
2702
- iusdAssetInfo.iassetTokenNameAscii,
2703
- adaAssetClass,
2704
- ),
2705
- );
2706
-
2707
- const resultRobUtxo1 = await findSingleRob(
2708
- context,
2709
- sysParams,
2710
- iusdAssetInfo.iassetTokenNameAscii,
2711
- paymentCredentialOf(context.users.user1.address),
2712
- );
2713
- const resultRobUtxo2 = await findSingleRob(
2714
- context,
2715
- sysParams,
2716
- iusdAssetInfo.iassetTokenNameAscii,
2717
- paymentCredentialOf(context.users.user2.address),
2718
- );
2719
-
2720
- const iassetAc: AssetClass = {
2721
- currencySymbol: fromHex(
2722
- sysParams.robParams.iassetPolicyId.unCurrencySymbol,
2723
- ),
2724
- tokenName: fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
2725
- };
2726
-
2727
- expectValue(resultRobUtxo1.utxo.assets, 'Wrong ROB1 value').toEqual(
2728
- addAssets(
2729
- mkLovelacesOf(MIN_ROB_COLLATERAL_AMT + 10_000_000n),
2730
- mkAssetsOf(
2731
- iassetAc,
2732
- initialDeposit -
2733
- 10_000_000n +
2734
- calculateFeeFromRatio(
2735
- (
2736
- await findIAssetNew(
2737
- context.lucid,
2738
- sysParams,
2739
- fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
2740
- )
2741
- ).datum.redemptionReimbursementRatio,
2742
- 10_000_000n,
2743
- ),
2744
- ),
2745
- ),
2746
- );
2747
-
2748
- expectValue(resultRobUtxo2.utxo.assets, 'Wrong ROB2 value').toEqual(
2749
- addAssets(
2750
- mkLovelacesOf(MIN_ROB_COLLATERAL_AMT + 11_000_000n),
2751
- mkAssetsOf(
2752
- iassetAc,
2753
- initialDeposit -
2754
- 11_000_000n +
2755
- calculateFeeFromRatio(
2756
- (
2757
- await findIAssetNew(
2758
- context.lucid,
2759
- sysParams,
2760
- fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
2761
- )
2762
- ).datum.redemptionReimbursementRatio,
2763
- 11_000_000n,
2764
- ),
2765
- ),
2766
- ),
2767
- );
2768
- });
2769
-
2770
- test<MyContext>('multi redemption BUY ROBs case (20 ROBs)', async (context: MyContext) => {
2771
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
2772
-
2773
- const [sysParams, [iusdAssetInfo]] = await init(context.lucid, [
2774
- iusdInitialAssetCfg(),
2775
- ]);
2776
-
2777
- const initialDeposit = 20_000_000n;
2778
-
2779
- context.lucid.selectWallet.fromSeed(context.users.user1.seedPhrase);
2780
-
2781
- await repeat(19, async () => {
2782
- // Adjsuted for Pyth updates
2783
- await runAndAwaitTx(
2784
- context.lucid,
2785
- openRob(
2786
- iusdAssetInfo.iassetTokenNameAscii,
2787
- initialDeposit,
2788
- {
2789
- BuyIAssetOrder: {
2790
- collateralAsset: adaAssetClass,
2791
- maxPrice: rationalFromInt(1n),
2792
- },
2793
- },
2794
- context.lucid,
2795
- sysParams,
2796
- ),
2797
- );
2798
- });
2799
-
2800
- const allRobs = await findAllRobs(
2801
- context.lucid,
2802
- sysParams,
2803
- iusdAssetInfo.iassetTokenNameAscii,
2804
- );
2805
-
2806
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
2807
-
2808
- await runAndAwaitTx(
2809
- context.lucid,
2810
- runOpenCdp(
2811
- context,
2812
- sysParams,
2813
- iusdAssetInfo.iassetTokenNameAscii,
2814
- adaAssetClass,
2815
- 100_000_000n,
2816
- 30_000_000n,
2817
- ),
2818
- );
2819
-
2820
- await benchmarkAndAwaitTx(
2821
- 'ROB - redeem 20 buy orders',
2822
- await runRedeemRob(
2823
- context,
2824
- sysParams,
2825
- allRobs.map((rob) => [rob, 1_000_000n]),
2826
- iusdAssetInfo.iassetTokenNameAscii,
2827
- adaAssetClass,
2828
- ),
2829
- context.lucid,
2830
- context.emulator,
2831
- );
2832
- });
2833
-
2834
- test<MyContext>('multi redemption SELL ROBs case single allowed collateral (18 ROBs)', async (context: MyContext) => {
2835
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
2836
-
2837
- const [sysParams, [iusdAssetInfo]] = await init(context.lucid, [
2838
- iusdInitialAssetCfg(),
2839
- ]);
2840
-
2841
- const initialDeposit = 5_000_000n;
2842
-
2843
- context.lucid.selectWallet.fromSeed(context.users.user1.seedPhrase);
2844
- await runAndAwaitTx(
2845
- context.lucid,
2846
- runOpenCdp(
2847
- context,
2848
- sysParams,
2849
- iusdAssetInfo.iassetTokenNameAscii,
2850
- adaAssetClass,
2851
- 1_000_000_000n,
2852
- initialDeposit * 18n +
2853
- // Should cover the minting fee
2854
- 1_000_000n,
2855
- ),
2856
- );
2857
-
2858
- await repeat(18, async () => {
2859
- await runAndAwaitTx(
2860
- context.lucid,
2861
- openRob(
2862
- iusdAssetInfo.iassetTokenNameAscii,
2863
- initialDeposit,
2864
- {
2865
- SellIAssetOrder: {
2866
- allowedCollateralAssets: [[adaAssetClass, rationalFromInt(1n)]],
2867
- },
2868
- },
2869
- context.lucid,
2870
- sysParams,
2871
- ),
2872
- );
2873
- });
2874
-
2875
- const allRobs = await findAllRobs(
2876
- context.lucid,
2877
- sysParams,
2878
- iusdAssetInfo.iassetTokenNameAscii,
2879
- );
2880
-
2881
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
2882
-
2883
- await benchmarkAndAwaitTx(
2884
- 'ROB - redeem 18 SELL orders, single allowed collateral',
2885
- await runRedeemRob(
2886
- context,
2887
- sysParams,
2888
- allRobs.map((rob) => [rob, 1_000_000n]),
2889
- iusdAssetInfo.iassetTokenNameAscii,
2890
- adaAssetClass,
2891
- ),
2892
- context.lucid,
2893
- context.emulator,
2894
- );
2895
- });
2896
-
2897
- test<MyContext>('Redeem buy order with expired oracle fails', async (context: MyContext) => {
2898
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
2899
-
2900
- const [sysParams, [iusdAssetInfo]] = await init(context.lucid, [
2901
- iusdInitialAssetCfg(),
2902
- ]);
2903
-
2904
- const [ownPkh, _] = await addrDetails(context.lucid);
2905
-
2906
- await runAndAwaitTx(
2907
- context.lucid,
2908
- runOpenCdp(
2909
- context,
2910
- sysParams,
2911
- iusdAssetInfo.iassetTokenNameAscii,
2912
- adaAssetClass,
2913
- 100_000_000n,
2914
- 30_000_000n,
2915
- ),
2916
- );
2917
-
2918
- await runAndAwaitTx(
2919
- context.lucid,
2920
- openRob(
2921
- iusdAssetInfo.iassetTokenNameAscii,
2922
- 20_000_000n,
2923
- {
2924
- BuyIAssetOrder: {
2925
- collateralAsset: adaAssetClass,
2926
- maxPrice: rationalFromInt(1n),
2927
- },
2928
- },
2929
- context.lucid,
2930
- sysParams,
2931
- ),
2932
- );
2933
-
2934
- const robUtxo = await findSingleRob(
2935
- context,
2936
- sysParams,
2937
- iusdAssetInfo.iassetTokenNameAscii,
2938
- ownPkh,
2939
- );
2940
-
2941
- const iassetAc: AssetClass = {
2942
- currencySymbol: fromHex(
2943
- sysParams.robParams.iassetPolicyId.unCurrencySymbol,
2944
- ),
2945
- tokenName: fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
2946
- };
2947
-
2948
- expect(
2949
- assetClassValueOf(robUtxo.utxo.assets, iassetAc),
2950
- 'ROB should have no iassets before redemption',
2951
- ).toBe(0n);
2952
-
2953
- const redemptionIAssetAmt = 11_000_000n;
2954
-
2955
- //Await until oracle is expired
2956
- await waitForOracleExpiration(
2957
- context,
2958
- sysParams,
2959
- iusdAssetInfo.iassetTokenNameAscii,
2960
- adaAssetClass,
2961
- );
2962
-
2963
- await expectScriptFailure(
2964
- 'X',
2965
- testRedeemRob(
2966
- [[robUtxo.utxo, redemptionIAssetAmt]],
2967
- await findPriceOracleFromCollateralAsset(
2968
- context.lucid,
2969
- await findCollateralAssetNew(
2970
- context.lucid,
2971
- sysParams,
2972
- fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
2973
- adaAssetClass,
2974
- ),
2975
- ),
2976
- (
2977
- await findIAssetNew(
2978
- context.lucid,
2979
- sysParams,
2980
- fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
2981
- )
2982
- ).utxo,
2983
- (
2984
- await findCollateralAssetNew(
2985
- context.lucid,
2986
- sysParams,
2987
- fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
2988
- adaAssetClass,
2989
- )
2990
- ).utxo,
2991
- context.lucid,
2992
-
2993
- sysParams,
2994
- ),
2995
- );
2996
- });
2997
-
2998
- test<MyContext>('Redeem sell order with expired oracle fails', async (context: MyContext) => {
2999
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
3000
-
3001
- const [sysParams, [iusdAssetInfo]] = await init(context.lucid, [
3002
- iusdInitialAssetCfg(),
3003
- ]);
3004
-
3005
- const [ownPkh, _] = await addrDetails(context.lucid);
3006
-
3007
- await runAndAwaitTx(
3008
- context.lucid,
3009
- runOpenCdp(
3010
- context,
3011
- sysParams,
3012
- iusdAssetInfo.iassetTokenNameAscii,
3013
- adaAssetClass,
3014
- 100_000_000n,
3015
- 30_000_000n,
3016
- ),
3017
- );
3018
-
3019
- await runAndAwaitTx(
3020
- context.lucid,
3021
- openRob(
3022
- iusdAssetInfo.iassetTokenNameAscii,
3023
- 20_000_000n,
3024
- {
3025
- SellIAssetOrder: {
3026
- allowedCollateralAssets: [[adaAssetClass, rationalFromInt(1n)]],
3027
- },
3028
- },
3029
- context.lucid,
3030
- sysParams,
3031
- ),
3032
- );
3033
-
3034
- const robUtxo = await findSingleRob(
3035
- context,
3036
- sysParams,
3037
- iusdAssetInfo.iassetTokenNameAscii,
3038
- ownPkh,
3039
- );
3040
-
3041
- const iassetAc: AssetClass = {
3042
- currencySymbol: fromHex(
3043
- sysParams.robParams.iassetPolicyId.unCurrencySymbol,
3044
- ),
3045
- tokenName: fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
3046
- };
3047
-
3048
- expect(
3049
- assetClassValueOf(robUtxo.utxo.assets, iassetAc),
3050
- 'ROB should have no iassets before redemption',
3051
- ).toBe(20_000_000n);
3052
-
3053
- const redemptionIAssetAmt = 11_000_000n;
3054
-
3055
- //Await until oracle is expired
3056
- await waitForOracleExpiration(
3057
- context,
3058
- sysParams,
3059
- iusdAssetInfo.iassetTokenNameAscii,
3060
- adaAssetClass,
3061
- );
3062
-
3063
- await expectScriptFailure(
3064
- 'X',
3065
- testRedeemRob(
3066
- [[robUtxo.utxo, redemptionIAssetAmt]],
3067
- await findPriceOracleFromCollateralAsset(
3068
- context.lucid,
3069
- await findCollateralAssetNew(
3070
- context.lucid,
3071
- sysParams,
3072
- fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
3073
- adaAssetClass,
3074
- ),
3075
- ),
3076
- (
3077
- await findIAssetNew(
3078
- context.lucid,
3079
- sysParams,
3080
- fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
3081
- )
3082
- ).utxo,
3083
- (
3084
- await findCollateralAssetNew(
3085
- context.lucid,
3086
- sysParams,
3087
- fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
3088
- adaAssetClass,
3089
- )
3090
- ).utxo,
3091
- context.lucid,
3092
-
3093
- sysParams,
3094
- ),
3095
- );
3096
- });
3097
-
3098
- test<IndigoTestContext>('Redeem with delisted iAsset fails', async (context: IndigoTestContext) => {
3099
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
3100
-
3101
- const [sysParams, [iusdAssetInfo]] = await init(context.lucid, [
3102
- iusdInitialAssetCfg(),
3103
- ]);
3104
-
3105
- const [ownPkh, _] = await addrDetails(context.lucid);
3106
-
3107
- await runAndAwaitTx(
3108
- context.lucid,
3109
- runOpenCdp(
3110
- context,
3111
- sysParams,
3112
- iusdAssetInfo.iassetTokenNameAscii,
3113
- adaAssetClass,
3114
- 100_000_000n,
3115
- 30_000_000n,
3116
- ),
3117
- );
3118
-
3119
- await runAndAwaitTx(
3120
- context.lucid,
3121
- openRob(
3122
- iusdAssetInfo.iassetTokenNameAscii,
3123
- 20_000_000n,
3124
- {
3125
- BuyIAssetOrder: {
3126
- collateralAsset: adaAssetClass,
3127
- maxPrice: rationalFromInt(1n),
3128
- },
3129
- },
3130
- context.lucid,
3131
- sysParams,
3132
- ),
3133
- );
3134
-
3135
- const robUtxo = await findSingleRob(
3136
- context,
3137
- sysParams,
3138
- iusdAssetInfo.iassetTokenNameAscii,
3139
- ownPkh,
3140
- );
3141
-
3142
- const iassetAc: AssetClass = {
3143
- currencySymbol: fromHex(
3144
- sysParams.robParams.iassetPolicyId.unCurrencySymbol,
3145
- ),
3146
- tokenName: fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
3147
- };
3148
-
3149
- expect(
3150
- assetClassValueOf(robUtxo.utxo.assets, iassetAc),
3151
- 'ROB should have no iassets before redemption',
3152
- ).toBe(0n);
3153
-
3154
- const redemptionIAssetAmt = 11_000_000n;
3155
-
3156
- const govUtxo = await findGov(
3157
- context.lucid,
3158
- sysParams.validatorHashes.govHash,
3159
- fromSystemParamsAsset(sysParams.govParams.govNFT),
3160
- );
3161
-
3162
- const collateralAssetToModify = await findCollateralAsset(
3163
- context.lucid,
3164
- sysParams,
3165
- fromSystemParamsAsset(sysParams.cdpCreatorParams.collateralAssetAuthTk),
3166
- iusdAssetInfo.iassetTokenNameAscii,
3167
- adaAssetClass,
3168
- );
3169
-
3170
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
3171
-
3172
- const [tx, pollId] = await createProposal(
3173
- {
3174
- UpdateCollateralAsset: {
3175
- correspondingIAsset: fromHex(fromText('iUSD')),
3176
- collateralAsset: adaAssetClass,
3177
- newAssetExtraDecimals: 0n,
3178
- newAssetPriceInfo: {
3179
- Delisted: { price: rationalFromInt(1n) },
3180
- },
3181
- newInterestOracleNft: collateralAssetToModify.datum.interestOracleNft,
3182
- newLiquidationRatio: rationalFromInt(1n),
3183
- newMaintenanceRatio: rationalFromInt(1n),
3184
- newRedemptionRatio: rationalFromInt(100n),
3185
- newMinCollateralAmt: collateralAssetToModify.datum.minCollateralAmt,
3186
- },
3187
- },
3188
- null,
3189
- sysParams,
3190
- context.lucid,
3191
- govUtxo.utxo,
3192
- [],
3193
- );
3194
-
3195
- await runAndAwaitTxBuilder(context.lucid, tx);
3196
-
3197
- await processSuccessfulProposal(
3198
- pollId,
3199
- null,
3200
- null,
3201
- null,
3202
- null,
3203
- collateralAssetToModify.utxo,
3204
- null,
3205
- sysParams,
3206
- context,
3207
- );
3208
-
3209
- {
3210
- const orefs = await findAllNecessaryOrefs(
3211
- context.lucid,
3212
- sysParams,
3213
- iusdAssetInfo.iassetTokenNameAscii,
3214
- adaAssetClass,
3215
- );
3216
-
3217
- await expectScriptFailure(
3218
- 'W',
3219
- testRedeemRob(
3220
- [[robUtxo.utxo, redemptionIAssetAmt]],
3221
- undefined,
3222
- orefs.iasset.utxo,
3223
- orefs.collateralAsset.utxo,
3224
- context.lucid,
3225
-
3226
- sysParams,
3227
- ),
3228
- );
3229
- }
3230
- });
3231
-
3232
- test<MyContext>('BUY order redemption, collateral with more decimal digits', async (context: MyContext) => {
3233
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
3234
-
3235
- const extraDecimals = 2n;
3236
-
3237
- const [sysParams, [iusdAssetInfo]] = await init(context.lucid, [
3238
- {
3239
- ...iusdInitialAssetCfg(),
3240
- collateralAssets: [
3241
- mkBaseCollateralAsset(
3242
- collateralAssetA,
3243
- 0n,
3244
- rationalFromInt(1n),
3245
- extraDecimals,
3246
- ),
3247
- ],
3248
- },
3249
- ]);
3250
-
3251
- const [ownPkh, _] = await addrDetails(context.lucid);
3252
-
3253
- await runAndAwaitTx(
3254
- context.lucid,
3255
- runOpenCdp(
3256
- context,
3257
- sysParams,
3258
- iusdAssetInfo.iassetTokenNameAscii,
3259
- collateralAssetA,
3260
- 10_000_000_000n,
3261
- 30_000_000n,
3262
- ),
3263
- );
3264
-
3265
- const robOrderAmount = 2_000_000_000n;
3266
-
3267
- await runAndAwaitTx(
3268
- context.lucid,
3269
- openRob(
3270
- iusdAssetInfo.iassetTokenNameAscii,
3271
- robOrderAmount,
3272
- {
3273
- BuyIAssetOrder: {
3274
- collateralAsset: collateralAssetA,
3275
- maxPrice: rationalFromInt(100n),
3276
- },
3277
- },
3278
- context.lucid,
3279
- sysParams,
3280
- ),
3281
- );
3282
-
3283
- const robUtxo = await findSingleRob(
3284
- context,
3285
- sysParams,
3286
- iusdAssetInfo.iassetTokenNameAscii,
3287
- ownPkh,
3288
- );
3289
-
3290
- const iassetAc: AssetClass = {
3291
- currencySymbol: fromHex(
3292
- sysParams.robParams.iassetPolicyId.unCurrencySymbol,
3293
- ),
3294
- tokenName: fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
3295
- };
3296
-
3297
- expect(
3298
- assetClassValueOf(robUtxo.utxo.assets, iassetAc),
3299
- 'ROB should have no iassets before redemption',
3300
- ).toBe(0n);
3301
-
3302
- const payoutIAssetAmt = 11_000_000n;
3303
-
3304
- await runAndAwaitTx(
3305
- context.lucid,
3306
- runRedeemRob(
3307
- context,
3308
- sysParams,
3309
- [[robUtxo, payoutIAssetAmt]],
3310
- iusdAssetInfo.iassetTokenNameAscii,
3311
- collateralAssetA,
3312
- ),
3313
- );
3314
-
3315
- const redeemedRob = await findSingleRob(
3316
- context,
3317
- sysParams,
3318
- iusdAssetInfo.iassetTokenNameAscii,
3319
- ownPkh,
3320
- );
3321
-
3322
- expect(
3323
- assetClassValueOf(redeemedRob.utxo.assets, iassetAc),
3324
- 'ROB has wrong number of iassets after redemption',
3325
- ).toBe(payoutIAssetAmt);
3326
-
3327
- expect(
3328
- assetClassValueOf(redeemedRob.utxo.assets, collateralAssetA),
3329
- 'ROB has wrong number of collateral asset after redemption',
3330
- ).toBe(
3331
- robOrderAmount -
3332
- (payoutIAssetAmt -
3333
- rationalFloor(
3334
- rationalMul(
3335
- rationalFromInt(payoutIAssetAmt),
3336
- iusdInitialAssetCfg().redemptionReimbursementRatio,
3337
- ),
3338
- )) *
3339
- 10n ** extraDecimals,
3340
- );
3341
- });
3342
-
3343
- test<MyContext>('BUY order redemption, collateral with less decimal digits', async (context: MyContext) => {
3344
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
3345
-
3346
- const extraDecimals = -2n;
3347
-
3348
- const [sysParams, [iusdAssetInfo]] = await init(context.lucid, [
3349
- {
3350
- ...iusdInitialAssetCfg(),
3351
- collateralAssets: [
3352
- mkBaseCollateralAsset(
3353
- collateralAssetA,
3354
- 0n,
3355
- rationalFromInt(1n),
3356
- extraDecimals,
3357
- ),
3358
- ],
3359
- },
3360
- ]);
3361
-
3362
- const [ownPkh, _] = await addrDetails(context.lucid);
3363
-
3364
- await runAndAwaitTx(
3365
- context.lucid,
3366
- runOpenCdp(
3367
- context,
3368
- sysParams,
3369
- iusdAssetInfo.iassetTokenNameAscii,
3370
- collateralAssetA,
3371
- 10_000_000n,
3372
- 300_000_000n,
3373
- ),
3374
- );
3375
-
3376
- const robOrderAmount = 200_000n;
3377
-
3378
- await runAndAwaitTx(
3379
- context.lucid,
3380
- openRob(
3381
- iusdAssetInfo.iassetTokenNameAscii,
3382
- robOrderAmount,
3383
- {
3384
- BuyIAssetOrder: {
3385
- collateralAsset: collateralAssetA,
3386
- maxPrice: { numerator: 1n, denominator: 100n },
3387
- },
3388
- },
3389
- context.lucid,
3390
- sysParams,
3391
- ),
3392
- );
3393
-
3394
- const robUtxo = await findSingleRob(
3395
- context,
3396
- sysParams,
3397
- iusdAssetInfo.iassetTokenNameAscii,
3398
- ownPkh,
3399
- );
3400
-
3401
- const iassetAc: AssetClass = {
3402
- currencySymbol: fromHex(
3403
- sysParams.robParams.iassetPolicyId.unCurrencySymbol,
3404
- ),
3405
- tokenName: fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
3406
- };
3407
-
3408
- expect(
3409
- assetClassValueOf(robUtxo.utxo.assets, iassetAc),
3410
- 'ROB should have no iassets before redemption',
3411
- ).toBe(0n);
3412
-
3413
- const payoutIAssetAmt = 11_000_000n;
3414
-
3415
- await runAndAwaitTx(
3416
- context.lucid,
3417
- runRedeemRob(
3418
- context,
3419
- sysParams,
3420
- [[robUtxo, payoutIAssetAmt]],
3421
- iusdAssetInfo.iassetTokenNameAscii,
3422
- collateralAssetA,
3423
- ),
3424
- );
3425
-
3426
- const redeemedRob = await findSingleRob(
3427
- context,
3428
- sysParams,
3429
- iusdAssetInfo.iassetTokenNameAscii,
3430
- ownPkh,
3431
- );
3432
-
3433
- expect(
3434
- assetClassValueOf(redeemedRob.utxo.assets, iassetAc),
3435
- 'ROB has wrong number of iassets after redemption',
3436
- ).toBe(payoutIAssetAmt);
3437
-
3438
- expect(
3439
- assetClassValueOf(redeemedRob.utxo.assets, collateralAssetA),
3440
- 'ROB has wrong number of collateral asset after redemption',
3441
- ).toBe(
3442
- robOrderAmount -
3443
- (payoutIAssetAmt -
3444
- rationalFloor(
3445
- rationalMul(
3446
- rationalFromInt(payoutIAssetAmt),
3447
- iusdInitialAssetCfg().redemptionReimbursementRatio,
3448
- ),
3449
- )) /
3450
- 10n ** -extraDecimals,
3451
- );
3452
- });
3453
-
3454
- test<MyContext>('SELL order redemption, collateral with more decimal digits', async (context: MyContext) => {
3455
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
3456
-
3457
- const extraDecimals = 2n;
3458
-
3459
- const [sysParams, [iusdAssetInfo]] = await init(context.lucid, [
3460
- {
3461
- ...iusdInitialAssetCfg(),
3462
- collateralAssets: [
3463
- mkBaseCollateralAsset(
3464
- collateralAssetA,
3465
- 0n,
3466
- rationalFromInt(1n),
3467
- extraDecimals,
3468
- ),
3469
- ],
3470
- },
3471
- ]);
3472
-
3473
- const [ownPkh, _] = await addrDetails(context.lucid);
3474
-
3475
- await runAndAwaitTx(
3476
- context.lucid,
3477
- runOpenCdp(
3478
- context,
3479
- sysParams,
3480
- iusdAssetInfo.iassetTokenNameAscii,
3481
- collateralAssetA,
3482
- 10_000_000_000n,
3483
- 30_000_000n,
3484
- ),
3485
- );
3486
-
3487
- const robOrderAmount = 20_000_000n;
3488
-
3489
- await runAndAwaitTx(
3490
- context.lucid,
3491
- openRob(
3492
- iusdAssetInfo.iassetTokenNameAscii,
3493
- robOrderAmount,
3494
- {
3495
- SellIAssetOrder: {
3496
- allowedCollateralAssets: [
3497
- [collateralAssetA, rationalFromInt(100n)],
3498
- ],
3499
- },
3500
- },
3501
- context.lucid,
3502
- sysParams,
3503
- ),
3504
- );
3505
-
3506
- const robUtxo = await findSingleRob(
3507
- context,
3508
- sysParams,
3509
- iusdAssetInfo.iassetTokenNameAscii,
3510
- ownPkh,
3511
- );
3512
-
3513
- const iassetAc: AssetClass = {
3514
- currencySymbol: fromHex(
3515
- sysParams.robParams.iassetPolicyId.unCurrencySymbol,
3516
- ),
3517
- tokenName: fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
3518
- };
3519
-
3520
- expect(
3521
- assetClassValueOf(robUtxo.utxo.assets, collateralAssetA),
3522
- 'ROB should have no collateral assets before redemption',
3523
- ).toBe(0n);
3524
-
3525
- const payoutCollateralAmt = 1_100_000_000n;
3526
-
3527
- await runAndAwaitTx(
3528
- context.lucid,
3529
- runRedeemRob(
3530
- context,
3531
- sysParams,
3532
- [[robUtxo, payoutCollateralAmt]],
3533
- iusdAssetInfo.iassetTokenNameAscii,
3534
- collateralAssetA,
3535
- ),
3536
- );
3537
-
3538
- const redeemedRob = await findSingleRob(
3539
- context,
3540
- sysParams,
3541
- iusdAssetInfo.iassetTokenNameAscii,
3542
- ownPkh,
3543
- );
3544
-
3545
- expect(
3546
- assetClassValueOf(redeemedRob.utxo.assets, iassetAc),
3547
- 'ROB has wrong number of iassets after redemption',
3548
- ).toBe(
3549
- robOrderAmount -
3550
- (payoutCollateralAmt -
3551
- rationalFloor(
3552
- rationalMul(
3553
- rationalFromInt(payoutCollateralAmt),
3554
- iusdInitialAssetCfg().redemptionReimbursementRatio,
3555
- ),
3556
- )) /
3557
- 10n ** extraDecimals,
3558
- );
3559
-
3560
- expect(
3561
- assetClassValueOf(redeemedRob.utxo.assets, collateralAssetA),
3562
- 'ROB has wrong number of collateral asset after redemption',
3563
- ).toBe(payoutCollateralAmt);
3564
- });
3565
-
3566
- test<MyContext>('SELL order redemption, collateral with less decimal digits', async (context: MyContext) => {
3567
- context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
3568
-
3569
- const extraDecimals = -2n;
3570
-
3571
- const [sysParams, [iusdAssetInfo]] = await init(context.lucid, [
3572
- {
3573
- ...iusdInitialAssetCfg(),
3574
- collateralAssets: [
3575
- mkBaseCollateralAsset(
3576
- collateralAssetA,
3577
- 0n,
3578
- rationalFromInt(1n),
3579
- extraDecimals,
3580
- ),
3581
- ],
3582
- },
3583
- ]);
3584
-
3585
- const [ownPkh, _] = await addrDetails(context.lucid);
3586
-
3587
- await runAndAwaitTx(
3588
- context.lucid,
3589
- runOpenCdp(
3590
- context,
3591
- sysParams,
3592
- iusdAssetInfo.iassetTokenNameAscii,
3593
- collateralAssetA,
3594
- 10_000_000n,
3595
- 300_000_000n,
3596
- ),
3597
- );
3598
-
3599
- const robOrderAmount = 20_000_000n;
3600
-
3601
- await runAndAwaitTx(
3602
- context.lucid,
3603
- openRob(
3604
- iusdAssetInfo.iassetTokenNameAscii,
3605
- robOrderAmount,
3606
- {
3607
- SellIAssetOrder: {
3608
- allowedCollateralAssets: [
3609
- [collateralAssetA, { numerator: 1n, denominator: 100n }],
3610
- ],
3611
- },
3612
- },
3613
- context.lucid,
3614
- sysParams,
3615
- ),
3616
- );
3617
-
3618
- const robUtxo = await findSingleRob(
3619
- context,
3620
- sysParams,
3621
- iusdAssetInfo.iassetTokenNameAscii,
3622
- ownPkh,
3623
- );
3624
-
3625
- const iassetAc: AssetClass = {
3626
- currencySymbol: fromHex(
3627
- sysParams.robParams.iassetPolicyId.unCurrencySymbol,
3628
- ),
3629
- tokenName: fromHex(fromText(iusdAssetInfo.iassetTokenNameAscii)),
3630
- };
3631
-
3632
- expect(
3633
- assetClassValueOf(robUtxo.utxo.assets, collateralAssetA),
3634
- 'ROB should have no collateral assets before redemption',
3635
- ).toBe(0n);
3636
-
3637
- const payoutCollateralAmt = 110_000n;
3638
-
3639
- await runAndAwaitTx(
3640
- context.lucid,
3641
- runRedeemRob(
3642
- context,
3643
- sysParams,
3644
- [[robUtxo, payoutCollateralAmt]],
3645
- iusdAssetInfo.iassetTokenNameAscii,
3646
- collateralAssetA,
3647
- ),
3648
- );
3649
-
3650
- const redeemedRob = await findSingleRob(
3651
- context,
3652
- sysParams,
3653
- iusdAssetInfo.iassetTokenNameAscii,
3654
- ownPkh,
3655
- );
3656
-
3657
- expect(
3658
- assetClassValueOf(redeemedRob.utxo.assets, iassetAc),
3659
- 'ROB has wrong number of iassets after redemption',
3660
- ).toBe(
3661
- robOrderAmount -
3662
- (payoutCollateralAmt -
3663
- rationalFloor(
3664
- rationalMul(
3665
- rationalFromInt(payoutCollateralAmt),
3666
- iusdInitialAssetCfg().redemptionReimbursementRatio,
3667
- ),
3668
- )) *
3669
- 10n ** -extraDecimals,
3670
- );
3671
-
3672
- expect(
3673
- assetClassValueOf(redeemedRob.utxo.assets, collateralAssetA),
3674
- 'ROB has wrong number of collateral asset after redemption',
3675
- ).toBe(payoutCollateralAmt);
3676
- });
3677
- });