@indigo-labs/indigo-sdk 0.5.4 → 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 (208) hide show
  1. package/dist/index.d.mts +11 -1
  2. package/dist/index.d.ts +11 -1
  3. package/dist/index.js +17 -0
  4. package/dist/index.mjs +15 -0
  5. package/package.json +11 -1
  6. package/.claude/settings.local.json +0 -7
  7. package/.github/workflows/ci.yml +0 -66
  8. package/.husky/pre-commit +0 -1
  9. package/.nvmrc +0 -1
  10. package/.prettierignore +0 -1
  11. package/.prettierrc +0 -6
  12. package/eslint.config.mjs +0 -42
  13. package/scripts/bench.sh +0 -62
  14. package/scripts/run-repeat.sh +0 -22
  15. package/src/contracts/cdp/helpers.ts +0 -173
  16. package/src/contracts/cdp/scripts.ts +0 -70
  17. package/src/contracts/cdp/transactions.ts +0 -1584
  18. package/src/contracts/cdp/types-new.ts +0 -277
  19. package/src/contracts/cdp/types.ts +0 -43
  20. package/src/contracts/cdp-creator/queries.ts +0 -30
  21. package/src/contracts/cdp-creator/scripts.ts +0 -45
  22. package/src/contracts/cdp-creator/types-new.ts +0 -50
  23. package/src/contracts/cdp-creator/types.ts +0 -24
  24. package/src/contracts/collector/scripts.ts +0 -32
  25. package/src/contracts/collector/transactions.ts +0 -50
  26. package/src/contracts/collector/types-new.ts +0 -17
  27. package/src/contracts/execute/scripts.ts +0 -57
  28. package/src/contracts/execute/types-new.ts +0 -44
  29. package/src/contracts/execute/types.ts +0 -24
  30. package/src/contracts/gov/helpers.ts +0 -351
  31. package/src/contracts/gov/scripts.ts +0 -41
  32. package/src/contracts/gov/transactions.ts +0 -1607
  33. package/src/contracts/gov/types-new.ts +0 -268
  34. package/src/contracts/gov/types.ts +0 -22
  35. package/src/contracts/iasset/helpers.ts +0 -170
  36. package/src/contracts/iasset/queries.ts +0 -102
  37. package/src/contracts/iasset/scripts.ts +0 -38
  38. package/src/contracts/iasset/types.ts +0 -154
  39. package/src/contracts/initialize/actions.ts +0 -789
  40. package/src/contracts/initialize/helpers.ts +0 -616
  41. package/src/contracts/initialize/types.ts +0 -116
  42. package/src/contracts/interest-collection/helpers.ts +0 -19
  43. package/src/contracts/interest-collection/queries.ts +0 -66
  44. package/src/contracts/interest-collection/scripts.ts +0 -44
  45. package/src/contracts/interest-collection/transactions.ts +0 -433
  46. package/src/contracts/interest-collection/types-new.ts +0 -50
  47. package/src/contracts/interest-collection/types.ts +0 -26
  48. package/src/contracts/interest-oracle/helpers.ts +0 -61
  49. package/src/contracts/interest-oracle/scripts.ts +0 -18
  50. package/src/contracts/interest-oracle/transactions.ts +0 -151
  51. package/src/contracts/interest-oracle/types-new.ts +0 -32
  52. package/src/contracts/interest-oracle/types.ts +0 -16
  53. package/src/contracts/one-shot/scripts.ts +0 -12
  54. package/src/contracts/one-shot/transactions.ts +0 -66
  55. package/src/contracts/one-shot/types.ts +0 -22
  56. package/src/contracts/poll/helpers.ts +0 -37
  57. package/src/contracts/poll/scripts.ts +0 -71
  58. package/src/contracts/poll/types-poll-manager.ts +0 -20
  59. package/src/contracts/poll/types-poll-new.ts +0 -196
  60. package/src/contracts/poll/types-poll-shard.ts +0 -16
  61. package/src/contracts/price-oracle/helpers.ts +0 -30
  62. package/src/contracts/price-oracle/scripts.ts +0 -18
  63. package/src/contracts/price-oracle/transactions.ts +0 -115
  64. package/src/contracts/price-oracle/types-new.ts +0 -50
  65. package/src/contracts/price-oracle/types.ts +0 -16
  66. package/src/contracts/pyth-feed/helpers.ts +0 -82
  67. package/src/contracts/pyth-feed/scripts.ts +0 -15
  68. package/src/contracts/pyth-feed/types.ts +0 -181
  69. package/src/contracts/rob/helpers.ts +0 -666
  70. package/src/contracts/rob/scripts.ts +0 -35
  71. package/src/contracts/rob/transactions.ts +0 -423
  72. package/src/contracts/rob/types-new.ts +0 -128
  73. package/src/contracts/rob/types.ts +0 -16
  74. package/src/contracts/rob-leverage/helpers.ts +0 -422
  75. package/src/contracts/rob-leverage/transactions.ts +0 -368
  76. package/src/contracts/stability-pool/helpers.ts +0 -798
  77. package/src/contracts/stability-pool/queries.ts +0 -132
  78. package/src/contracts/stability-pool/scripts.ts +0 -51
  79. package/src/contracts/stability-pool/transactions.ts +0 -921
  80. package/src/contracts/stability-pool/types-new.ts +0 -385
  81. package/src/contracts/stability-pool/types.ts +0 -25
  82. package/src/contracts/stableswap/helpers.ts +0 -507
  83. package/src/contracts/stableswap/scripts.ts +0 -37
  84. package/src/contracts/stableswap/transactions.ts +0 -475
  85. package/src/contracts/stableswap/types-new.ts +0 -131
  86. package/src/contracts/stableswap/types.ts +0 -17
  87. package/src/contracts/staking/helpers.ts +0 -136
  88. package/src/contracts/staking/scripts.ts +0 -41
  89. package/src/contracts/staking/transactions.ts +0 -349
  90. package/src/contracts/staking/types-new.ts +0 -137
  91. package/src/contracts/staking/types.ts +0 -17
  92. package/src/contracts/treasury/helpers.ts +0 -21
  93. package/src/contracts/treasury/queries.ts +0 -100
  94. package/src/contracts/treasury/scripts.ts +0 -27
  95. package/src/contracts/treasury/transactions.ts +0 -334
  96. package/src/contracts/treasury/types-new.ts +0 -69
  97. package/src/contracts/treasury/types.ts +0 -14
  98. package/src/contracts/version-registry/scripts.ts +0 -29
  99. package/src/contracts/version-registry/types-new.ts +0 -18
  100. package/src/contracts/version-registry/types.ts +0 -17
  101. package/src/index.ts +0 -93
  102. package/src/scripts/always-fail-validator.ts +0 -7
  103. package/src/scripts/auth-token-policy.ts +0 -24
  104. package/src/scripts/iasset-policy.ts +0 -23
  105. package/src/types/evolution-schema-options.ts +0 -16
  106. package/src/types/generic.ts +0 -52
  107. package/src/types/multisig.ts +0 -48
  108. package/src/types/on-chain-decimal.ts +0 -57
  109. package/src/types/rational.ts +0 -61
  110. package/src/types/system-params.ts +0 -463
  111. package/src/utils/array-utils.ts +0 -108
  112. package/src/utils/bigint-utils.ts +0 -35
  113. package/src/utils/helper-txs.ts +0 -31
  114. package/src/utils/indigo-helpers.ts +0 -17
  115. package/src/utils/lucid-utils.ts +0 -125
  116. package/src/utils/oracle-helpers.ts +0 -62
  117. package/src/utils/pyth/decode.ts +0 -223
  118. package/src/utils/pyth/encode.ts +0 -262
  119. package/src/utils/pyth/index.ts +0 -14
  120. package/src/utils/pyth/types.ts +0 -87
  121. package/src/utils/time-helpers.ts +0 -4
  122. package/src/utils/utils.ts +0 -25
  123. package/src/validators/always-succeed-validator.ts +0 -6
  124. package/src/validators/cdp-creator-validator.ts +0 -7
  125. package/src/validators/cdp-redeem-validator.ts +0 -7
  126. package/src/validators/cdp-validator.ts +0 -7
  127. package/src/validators/collector-validator.ts +0 -7
  128. package/src/validators/execute-validator.ts +0 -7
  129. package/src/validators/governance-validator.ts +0 -7
  130. package/src/validators/iasset-validator.ts +0 -7
  131. package/src/validators/interest-collection-validator.ts +0 -7
  132. package/src/validators/interest-oracle-validator.ts +0 -7
  133. package/src/validators/one-shot-policy.ts +0 -7
  134. package/src/validators/poll-manager-validator.ts +0 -7
  135. package/src/validators/poll-shard-validator.ts +0 -7
  136. package/src/validators/price-oracle-validator.ts +0 -7
  137. package/src/validators/pyth-feed-validator.ts +0 -7
  138. package/src/validators/rob-validator.ts +0 -7
  139. package/src/validators/stability-pool-validator.ts +0 -7
  140. package/src/validators/stableswap-validator.ts +0 -7
  141. package/src/validators/staking-validator.ts +0 -7
  142. package/src/validators/treasury-validator.ts +0 -7
  143. package/src/validators/version-record-policy.ts +0 -7
  144. package/src/validators/version-registry-validator.ts +0 -7
  145. package/tests/always-succeed/script.ts +0 -7
  146. package/tests/array-utils.test.ts +0 -92
  147. package/tests/bigint-utils.test.ts +0 -41
  148. package/tests/cdp/actions.ts +0 -680
  149. package/tests/cdp/cdp-helpers.ts +0 -55
  150. package/tests/cdp/cdp-queries.ts +0 -423
  151. package/tests/cdp/cdp.test.ts +0 -6730
  152. package/tests/cdp/transactions-mutated.ts +0 -1733
  153. package/tests/data/system-params.json +0 -1155
  154. package/tests/datums.test.ts +0 -302
  155. package/tests/endpoints/initialize.ts +0 -78
  156. package/tests/endpoints/interest-collector.ts +0 -37
  157. package/tests/endpoints/treasury.ts +0 -70
  158. package/tests/gov/actions.ts +0 -381
  159. package/tests/gov/gov.test.ts +0 -5147
  160. package/tests/gov/governance-queries.ts +0 -37
  161. package/tests/hash-checks.test.ts +0 -112
  162. package/tests/indigo-test-helpers.ts +0 -99
  163. package/tests/initialize.test.ts +0 -79
  164. package/tests/interest-calculations.test.ts +0 -120
  165. package/tests/interest-collection/interest-collection.test.ts +0 -843
  166. package/tests/interest-collection/transactions-mutated.ts +0 -260
  167. package/tests/interest-oracle.test.ts +0 -93
  168. package/tests/mock/assets-mock.ts +0 -243
  169. package/tests/mock/protocol-params-mock.ts +0 -21
  170. package/tests/price-oracle/actions.ts +0 -161
  171. package/tests/price-oracle/price-oracle-queries.ts +0 -12
  172. package/tests/price-oracle/price-oracle.test.ts +0 -228
  173. package/tests/price-oracle/transactions-mutated.ts +0 -59
  174. package/tests/pyth/endpoints.ts +0 -96
  175. package/tests/pyth/helpers.ts +0 -37
  176. package/tests/pyth/pyth-encoding.test.ts +0 -376
  177. package/tests/pyth/pyth-feeds.test.ts +0 -943
  178. package/tests/pyth/pyth-indigo.test.ts +0 -505
  179. package/tests/pyth/pyth.test.ts +0 -299
  180. package/tests/queries/collector-queries.ts +0 -27
  181. package/tests/queries/execute-queries.ts +0 -47
  182. package/tests/queries/iasset-queries.ts +0 -149
  183. package/tests/queries/interest-oracle-queries.ts +0 -12
  184. package/tests/queries/poll-queries.ts +0 -97
  185. package/tests/queries/staking-queries.ts +0 -54
  186. package/tests/rob/actions.ts +0 -56
  187. package/tests/rob/rob-leverage.test.ts +0 -2555
  188. package/tests/rob/rob-queries.ts +0 -95
  189. package/tests/rob/rob.test.ts +0 -3677
  190. package/tests/rob/transactions-mutated.ts +0 -844
  191. package/tests/script-size.test.ts +0 -240
  192. package/tests/setup.ts +0 -135
  193. package/tests/stability-pool/actions.ts +0 -229
  194. package/tests/stability-pool.test.ts +0 -6491
  195. package/tests/stableswap/stableswap-actions.ts +0 -83
  196. package/tests/stableswap/stableswap-queries.ts +0 -98
  197. package/tests/stableswap/stableswap.test.ts +0 -4471
  198. package/tests/stableswap/transactions-mutated.ts +0 -348
  199. package/tests/staking.test.ts +0 -172
  200. package/tests/test-helpers.ts +0 -94
  201. package/tests/treasury/actions.ts +0 -67
  202. package/tests/treasury/treasury.test.ts +0 -320
  203. package/tests/utils/asserts.ts +0 -87
  204. package/tests/utils/benchmark-utils.ts +0 -130
  205. package/tests/utils/index.ts +0 -168
  206. package/tsconfig.build.json +0 -4
  207. package/tsconfig.json +0 -27
  208. 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
- });