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