@indigo-labs/indigo-sdk 0.3.15 → 0.3.17
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 +2 -4
- package/dist/index.d.mts +40 -8
- package/dist/index.d.ts +40 -8
- package/dist/index.js +125 -69
- package/dist/index.mjs +124 -71
- package/package.json +2 -1
- package/scripts/bench.sh +62 -0
- package/src/contracts/iasset/helpers.ts +1 -1
- package/src/contracts/poll/types-poll-new.ts +10 -5
- package/src/contracts/rob/helpers.ts +122 -43
- package/src/contracts/rob/transactions.ts +12 -3
- package/src/contracts/rob-leverage/helpers.ts +4 -1
- package/src/contracts/stability-pool/types-new.ts +11 -5
- package/src/contracts/stableswap/transactions.ts +1 -5
- package/src/contracts/staking/types-new.ts +5 -3
- package/src/contracts/treasury/transactions.ts +8 -2
- package/src/validators/cdp-creator-validator.ts +1 -1
- package/src/validators/cdp-redeem-validator.ts +1 -1
- package/src/validators/cdp-validator.ts +1 -1
- package/src/validators/collector-validator.ts +1 -1
- package/src/validators/execute-validator.ts +1 -1
- package/src/validators/governance-validator.ts +1 -1
- package/src/validators/iasset-validator.ts +1 -1
- package/src/validators/interest-collection-validator.ts +1 -1
- package/src/validators/interest-oracle-validator.ts +1 -1
- package/src/validators/poll-manager-validator.ts +1 -1
- package/src/validators/poll-shard-validator.ts +1 -1
- package/src/validators/price-oracle-validator.ts +1 -1
- package/src/validators/pyth-feed-validator.ts +1 -1
- package/src/validators/rob-validator.ts +1 -1
- package/src/validators/stability-pool-validator.ts +1 -1
- package/src/validators/stableswap-validator.ts +1 -1
- package/src/validators/staking-validator.ts +1 -1
- package/src/validators/treasury-validator.ts +1 -1
- package/src/validators/version-record-policy.ts +1 -1
- package/tests/cdp/actions.ts +1 -1
- package/tests/cdp/cdp-queries.ts +1 -1
- package/tests/cdp/cdp.test.ts +1 -1
- package/tests/cdp/transactions-mutated.ts +1 -1
- package/tests/gov/gov.test.ts +78 -12
- package/tests/interest-collection/interest-collection.test.ts +5 -5
- package/tests/rob/rob-leverage.test.ts +12 -27
- package/tests/rob/rob.test.ts +56 -52
- package/tests/stability-pool.test.ts +7 -4
- package/tests/stableswap/stableswap.test.ts +1 -1
- package/tests/treasury/actions.ts +67 -0
- package/tests/{queries → treasury}/treasury-queries.ts +11 -2
- package/tests/treasury/treasury.test.ts +342 -0
- package/vitest.config.ts +1 -1
- package/tests/treasury.test.ts +0 -242
package/tests/rob/rob.test.ts
CHANGED
|
@@ -1126,8 +1126,8 @@ describe('ROB', () => {
|
|
|
1126
1126
|
);
|
|
1127
1127
|
|
|
1128
1128
|
const amtToSpendBefore = robCollateralAmtToSpend(
|
|
1129
|
-
robBefore.utxo,
|
|
1130
|
-
robBefore.datum,
|
|
1129
|
+
robBefore.utxo.assets,
|
|
1130
|
+
robBefore.datum.orderType,
|
|
1131
1131
|
);
|
|
1132
1132
|
|
|
1133
1133
|
await runAndAwaitTx(
|
|
@@ -1149,8 +1149,8 @@ describe('ROB', () => {
|
|
|
1149
1149
|
);
|
|
1150
1150
|
|
|
1151
1151
|
const amtToSpendAfter = robCollateralAmtToSpend(
|
|
1152
|
-
adjustedUtxo1.utxo,
|
|
1153
|
-
adjustedUtxo1.datum,
|
|
1152
|
+
adjustedUtxo1.utxo.assets,
|
|
1153
|
+
adjustedUtxo1.datum.orderType,
|
|
1154
1154
|
);
|
|
1155
1155
|
|
|
1156
1156
|
assert(amtToSpendBefore - amtToSpendAfter === 1_000_000n);
|
|
@@ -1170,8 +1170,8 @@ describe('ROB', () => {
|
|
|
1170
1170
|
);
|
|
1171
1171
|
|
|
1172
1172
|
const amtToSpendBefore = robCollateralAmtToSpend(
|
|
1173
|
-
robBefore.utxo,
|
|
1174
|
-
robBefore.datum,
|
|
1173
|
+
robBefore.utxo.assets,
|
|
1174
|
+
robBefore.datum.orderType,
|
|
1175
1175
|
);
|
|
1176
1176
|
|
|
1177
1177
|
await runAndAwaitTx(
|
|
@@ -1193,8 +1193,8 @@ describe('ROB', () => {
|
|
|
1193
1193
|
);
|
|
1194
1194
|
|
|
1195
1195
|
const amtToSpendAfter = robCollateralAmtToSpend(
|
|
1196
|
-
adjustedUtxo2.utxo,
|
|
1197
|
-
adjustedUtxo2.datum,
|
|
1196
|
+
adjustedUtxo2.utxo.assets,
|
|
1197
|
+
adjustedUtxo2.datum.orderType,
|
|
1198
1198
|
);
|
|
1199
1199
|
|
|
1200
1200
|
strictEqual(amtToSpendAfter - amtToSpendBefore, 5_000_000n);
|
|
@@ -1271,20 +1271,26 @@ describe('ROB', () => {
|
|
|
1271
1271
|
};
|
|
1272
1272
|
|
|
1273
1273
|
assert(
|
|
1274
|
-
robAmtToSpend(
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1274
|
+
robAmtToSpend(adjustedUtxo1.utxo.assets, adjustedUtxo1.datum.orderType, {
|
|
1275
|
+
currencySymbol: fromHex(
|
|
1276
|
+
sysParams.cdpParams.cdpAssetSymbol.unCurrencySymbol,
|
|
1277
|
+
),
|
|
1278
|
+
tokenName: adjustedUtxo1.datum.iasset,
|
|
1279
|
+
}) ===
|
|
1279
1280
|
20_000_000n - 1_000_000n,
|
|
1280
1281
|
);
|
|
1281
1282
|
|
|
1282
1283
|
expect(
|
|
1283
1284
|
assetClassValueOf(adjustedUtxo1.utxo.assets, iassetAc) ===
|
|
1284
1285
|
robAmtToSpend(
|
|
1285
|
-
adjustedUtxo1.utxo,
|
|
1286
|
-
adjustedUtxo1.datum,
|
|
1287
|
-
|
|
1286
|
+
adjustedUtxo1.utxo.assets,
|
|
1287
|
+
adjustedUtxo1.datum.orderType,
|
|
1288
|
+
{
|
|
1289
|
+
currencySymbol: fromHex(
|
|
1290
|
+
sysParams.cdpParams.cdpAssetSymbol.unCurrencySymbol,
|
|
1291
|
+
),
|
|
1292
|
+
tokenName: adjustedUtxo1.datum.iasset,
|
|
1293
|
+
},
|
|
1288
1294
|
),
|
|
1289
1295
|
'IAssets to spend has to equal iassets in UTXO',
|
|
1290
1296
|
).toBeTruthy();
|
|
@@ -1310,20 +1316,26 @@ describe('ROB', () => {
|
|
|
1310
1316
|
const expectedResultAdaAmt = 20_000_000n - 1_000_000n + 5_000_000n;
|
|
1311
1317
|
|
|
1312
1318
|
strictEqual(
|
|
1313
|
-
robAmtToSpend(
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1319
|
+
robAmtToSpend(adjustedUtxo2.utxo.assets, adjustedUtxo2.datum.orderType, {
|
|
1320
|
+
currencySymbol: fromHex(
|
|
1321
|
+
sysParams.cdpParams.cdpAssetSymbol.unCurrencySymbol,
|
|
1322
|
+
),
|
|
1323
|
+
tokenName: adjustedUtxo2.datum.iasset,
|
|
1324
|
+
}),
|
|
1318
1325
|
expectedResultAdaAmt,
|
|
1319
1326
|
);
|
|
1320
1327
|
|
|
1321
1328
|
expect(
|
|
1322
1329
|
assetClassValueOf(adjustedUtxo2.utxo.assets, iassetAc) >=
|
|
1323
1330
|
robAmtToSpend(
|
|
1324
|
-
adjustedUtxo2.utxo,
|
|
1325
|
-
adjustedUtxo2.datum,
|
|
1326
|
-
|
|
1331
|
+
adjustedUtxo2.utxo.assets,
|
|
1332
|
+
adjustedUtxo2.datum.orderType,
|
|
1333
|
+
{
|
|
1334
|
+
currencySymbol: fromHex(
|
|
1335
|
+
sysParams.cdpParams.cdpAssetSymbol.unCurrencySymbol,
|
|
1336
|
+
),
|
|
1337
|
+
tokenName: adjustedUtxo2.datum.iasset,
|
|
1338
|
+
},
|
|
1327
1339
|
),
|
|
1328
1340
|
'IAssets to spend has to equal iassets in UTXO',
|
|
1329
1341
|
).toBeTruthy();
|
|
@@ -1390,8 +1402,8 @@ describe('ROB', () => {
|
|
|
1390
1402
|
const redemptionIAssetAmt = 11_000_000n;
|
|
1391
1403
|
|
|
1392
1404
|
const amtToSpendBefore = robCollateralAmtToSpend(
|
|
1393
|
-
robUtxo.utxo,
|
|
1394
|
-
robUtxo.datum,
|
|
1405
|
+
robUtxo.utxo.assets,
|
|
1406
|
+
robUtxo.datum.orderType,
|
|
1395
1407
|
);
|
|
1396
1408
|
|
|
1397
1409
|
await runAndAwaitTx(
|
|
@@ -1420,7 +1432,10 @@ describe('ROB', () => {
|
|
|
1420
1432
|
|
|
1421
1433
|
expect(
|
|
1422
1434
|
amtToSpendBefore -
|
|
1423
|
-
robCollateralAmtToSpend(
|
|
1435
|
+
robCollateralAmtToSpend(
|
|
1436
|
+
redeemedRob.utxo.assets,
|
|
1437
|
+
redeemedRob.datum.orderType,
|
|
1438
|
+
),
|
|
1424
1439
|
'ROB has wrong number redeemed',
|
|
1425
1440
|
).toEqual(
|
|
1426
1441
|
// Since price is 1
|
|
@@ -1565,7 +1580,10 @@ describe('ROB', () => {
|
|
|
1565
1580
|
);
|
|
1566
1581
|
|
|
1567
1582
|
expect(
|
|
1568
|
-
robCollateralAmtToSpend(
|
|
1583
|
+
robCollateralAmtToSpend(
|
|
1584
|
+
redeemedRob.utxo.assets,
|
|
1585
|
+
redeemedRob.datum.orderType,
|
|
1586
|
+
),
|
|
1569
1587
|
'Wrong amt to spend in datum',
|
|
1570
1588
|
).toEqual(initialDeposit - expectedRedeemedAmt);
|
|
1571
1589
|
|
|
@@ -1713,11 +1731,12 @@ describe('ROB', () => {
|
|
|
1713
1731
|
);
|
|
1714
1732
|
|
|
1715
1733
|
expect(
|
|
1716
|
-
robAmtToSpend(
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1734
|
+
robAmtToSpend(redeemedRob.utxo.assets, redeemedRob.datum.orderType, {
|
|
1735
|
+
currencySymbol: fromHex(
|
|
1736
|
+
sysParams.cdpParams.cdpAssetSymbol.unCurrencySymbol,
|
|
1737
|
+
),
|
|
1738
|
+
tokenName: redeemedRob.datum.iasset,
|
|
1739
|
+
}),
|
|
1721
1740
|
'Wrong amt to spend in datum',
|
|
1722
1741
|
).toEqual(initialDeposit - expectedRedemptionAmt);
|
|
1723
1742
|
|
|
@@ -2223,24 +2242,6 @@ describe('ROB', () => {
|
|
|
2223
2242
|
|
|
2224
2243
|
const payoutIAssetAmt = 11_000_000n;
|
|
2225
2244
|
|
|
2226
|
-
// const expectedRedemptionAmt =(
|
|
2227
|
-
// {
|
|
2228
|
-
// getOnChainInt:
|
|
2229
|
-
// payoutCollateralAmt -
|
|
2230
|
-
// calculateFeeFromPercentage(
|
|
2231
|
-
// (
|
|
2232
|
-
// await findIAssetNew(
|
|
2233
|
-
// context,
|
|
2234
|
-
// sysParams,
|
|
2235
|
-
// iusdAssetInfo.iassetTokenNameAscii,
|
|
2236
|
-
// )
|
|
2237
|
-
// ).datum.redemptionReimbursementPercentage,
|
|
2238
|
-
// payoutCollateralAmt,
|
|
2239
|
-
// ),
|
|
2240
|
-
// },
|
|
2241
|
-
// newPrice,
|
|
2242
|
-
// ).getOnChainInt;
|
|
2243
|
-
|
|
2244
2245
|
await runAndAwaitTx(
|
|
2245
2246
|
context.lucid,
|
|
2246
2247
|
runRedeemRob(
|
|
@@ -2290,7 +2291,10 @@ describe('ROB', () => {
|
|
|
2290
2291
|
|
|
2291
2292
|
// Since price is 1
|
|
2292
2293
|
expect(
|
|
2293
|
-
robCollateralAmtToSpend(
|
|
2294
|
+
robCollateralAmtToSpend(
|
|
2295
|
+
adjustedRob.utxo.assets,
|
|
2296
|
+
adjustedRob.datum.orderType,
|
|
2297
|
+
),
|
|
2294
2298
|
).toEqual(
|
|
2295
2299
|
// 20mil start, -1mil adjusted, rest redeemed
|
|
2296
2300
|
20_000_000n -
|
|
@@ -1924,7 +1924,7 @@ describe('Stability pool', () => {
|
|
|
1924
1924
|
});
|
|
1925
1925
|
|
|
1926
1926
|
// These are the most significant tests for benchmarking the maximum number of collateral assets supported.
|
|
1927
|
-
describe('Liquidate', () => {
|
|
1927
|
+
describe.skip('Liquidate', () => {
|
|
1928
1928
|
test<MyContext>('Liquidate with 10 reward assets in the pool - collecting with 2 assets in treasury', async (context: MyContext) => {
|
|
1929
1929
|
context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
|
|
1930
1930
|
|
|
@@ -2317,7 +2317,7 @@ describe('Stability pool', () => {
|
|
|
2317
2317
|
}
|
|
2318
2318
|
});
|
|
2319
2319
|
|
|
2320
|
-
test<MyContext>('Liquidate with
|
|
2320
|
+
test<MyContext>('Liquidate with 10 reward assets in the pool and increasing epoch', async (context: MyContext) => {
|
|
2321
2321
|
context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
|
|
2322
2322
|
|
|
2323
2323
|
const initialAssets = [
|
|
@@ -2330,9 +2330,12 @@ describe('Stability pool', () => {
|
|
|
2330
2330
|
collateralAssetF,
|
|
2331
2331
|
collateralAssetG,
|
|
2332
2332
|
collateralAssetH,
|
|
2333
|
+
collateralAssetI,
|
|
2333
2334
|
];
|
|
2334
2335
|
|
|
2335
|
-
expect(initialAssets.length, 'Unexpected reward assets count').toEqual(
|
|
2336
|
+
expect(initialAssets.length, 'Unexpected reward assets count').toEqual(
|
|
2337
|
+
10,
|
|
2338
|
+
);
|
|
2336
2339
|
|
|
2337
2340
|
const [sysParams, [iusdAssetInfo]] = await init(
|
|
2338
2341
|
context.lucid,
|
|
@@ -2484,7 +2487,7 @@ describe('Stability pool', () => {
|
|
|
2484
2487
|
iusdAssetInfo,
|
|
2485
2488
|
async (tx) =>
|
|
2486
2489
|
benchmarkAndAwaitTx(
|
|
2487
|
-
'Stability Pool - Liquidate with
|
|
2490
|
+
'Stability Pool - Liquidate with 10 reward assets in the pool and increasing epoch',
|
|
2488
2491
|
tx,
|
|
2489
2492
|
context.lucid,
|
|
2490
2493
|
context.emulator,
|
|
@@ -60,7 +60,7 @@ import { expectScriptFailure } from '../utils/asserts';
|
|
|
60
60
|
import {
|
|
61
61
|
findRandomTreasuryUtxoWithOnlyAda,
|
|
62
62
|
findRandomTreasuryUtxoWithAsset,
|
|
63
|
-
} from '../
|
|
63
|
+
} from '../treasury/treasury-queries';
|
|
64
64
|
import { createUtxoAtTreasury } from '../endpoints/treasury';
|
|
65
65
|
import { rationalFromInt, rationalZero } from '../../src/types/rational';
|
|
66
66
|
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Assets, TxBuilder } from '@lucid-evolution/lucid';
|
|
2
|
+
import { LucidContext } from '../test-helpers';
|
|
3
|
+
import { createUtxoAtTreasury } from '../endpoints/treasury';
|
|
4
|
+
import { SystemParams, treasuryMerge, treasurySplit } from '../../src';
|
|
5
|
+
import { findAllTreasuryUtxos } from './treasury-queries';
|
|
6
|
+
import { assert } from 'vitest';
|
|
7
|
+
|
|
8
|
+
export async function treasuryMergeTx(
|
|
9
|
+
context: LucidContext,
|
|
10
|
+
sysParams: SystemParams,
|
|
11
|
+
treasuryOutputs: Assets[],
|
|
12
|
+
): Promise<TxBuilder> {
|
|
13
|
+
for (const output of treasuryOutputs) {
|
|
14
|
+
await createUtxoAtTreasury(output, sysParams, context);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const treasuryUtxos = await findAllTreasuryUtxos(context.lucid, sysParams);
|
|
18
|
+
|
|
19
|
+
// Simpler approach: for each expected output in treasuryOutputs, find one UTxO with exactly matching assets and take it
|
|
20
|
+
// Find UTxOs for each expected output, but remove it from the candidate list as we match
|
|
21
|
+
const availableUtxos = [...treasuryUtxos];
|
|
22
|
+
const matchedTreasuryUtxos = treasuryOutputs
|
|
23
|
+
.map((expectedAssets) => {
|
|
24
|
+
const idx = availableUtxos.findIndex((utxo) => {
|
|
25
|
+
const utxoAssets = utxo.assets;
|
|
26
|
+
const keys1 = Object.keys(utxoAssets).sort();
|
|
27
|
+
const keys2 = Object.keys(expectedAssets).sort();
|
|
28
|
+
if (keys1.length !== keys2.length) return false;
|
|
29
|
+
return keys1.every(
|
|
30
|
+
(k, i) => k === keys2[i] && utxoAssets[k] === expectedAssets[k],
|
|
31
|
+
);
|
|
32
|
+
});
|
|
33
|
+
if (idx !== -1) {
|
|
34
|
+
return availableUtxos.splice(idx, 1)[0];
|
|
35
|
+
} else {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
.filter((utxo) => utxo !== undefined);
|
|
40
|
+
|
|
41
|
+
assert(
|
|
42
|
+
matchedTreasuryUtxos.length === treasuryOutputs.length,
|
|
43
|
+
'Expected all treasury outputs to be matched',
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
return await treasuryMerge(matchedTreasuryUtxos, context.lucid, sysParams);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export async function treasurySplitTx(
|
|
50
|
+
context: LucidContext,
|
|
51
|
+
sysParams: SystemParams,
|
|
52
|
+
treasuryOutput: Assets,
|
|
53
|
+
): Promise<TxBuilder> {
|
|
54
|
+
await createUtxoAtTreasury(treasuryOutput, sysParams, context);
|
|
55
|
+
|
|
56
|
+
const treasuryUtxos = await findAllTreasuryUtxos(context.lucid, sysParams);
|
|
57
|
+
|
|
58
|
+
const matchedTreasuryUtxo = treasuryUtxos.find((utxo) =>
|
|
59
|
+
Object.keys(treasuryOutput).every(
|
|
60
|
+
(key) => utxo.assets[key] === treasuryOutput[key],
|
|
61
|
+
),
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
assert(matchedTreasuryUtxo !== undefined, 'Expected a single treasury UTXO');
|
|
65
|
+
|
|
66
|
+
return await treasurySplit(matchedTreasuryUtxo, context.lucid, sysParams);
|
|
67
|
+
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { LucidEvolution, UTxO } from '@lucid-evolution/lucid';
|
|
2
|
-
import { SystemParams } from '../../src';
|
|
2
|
+
import { fromSystemParamsAsset, SystemParams } from '../../src';
|
|
3
3
|
import { option as O, function as F } from 'fp-ts';
|
|
4
4
|
import {
|
|
5
5
|
AssetClass,
|
|
6
6
|
assetClassToUnit,
|
|
7
|
+
assetClassValueOf,
|
|
7
8
|
getRandomElement,
|
|
8
9
|
} from '@3rd-eye-labs/cardano-offchain-common';
|
|
9
10
|
|
|
@@ -85,6 +86,7 @@ export async function findAllTreasuryUtxos(
|
|
|
85
86
|
export async function findAllTreasuryUtxosWithNonAdaAsset(
|
|
86
87
|
lucid: LucidEvolution,
|
|
87
88
|
sysParams: SystemParams,
|
|
89
|
+
includeDaoToken: boolean = true,
|
|
88
90
|
): Promise<UTxO[]> {
|
|
89
91
|
// We need to consider both with staking credential and without.
|
|
90
92
|
const treasuryUtxos = await lucid.utxosAt({
|
|
@@ -93,7 +95,14 @@ export async function findAllTreasuryUtxosWithNonAdaAsset(
|
|
|
93
95
|
});
|
|
94
96
|
|
|
95
97
|
const treasuryUtxosWithNonAdaAsset = treasuryUtxos.filter(
|
|
96
|
-
(utxo) =>
|
|
98
|
+
(utxo) =>
|
|
99
|
+
Object.keys(utxo.assets).length !== 1 &&
|
|
100
|
+
(includeDaoToken
|
|
101
|
+
? true
|
|
102
|
+
: assetClassValueOf(
|
|
103
|
+
utxo.assets,
|
|
104
|
+
fromSystemParamsAsset(sysParams.govParams.daoIdentityToken),
|
|
105
|
+
) === 0n),
|
|
97
106
|
);
|
|
98
107
|
|
|
99
108
|
return treasuryUtxosWithNonAdaAsset;
|
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
import {
|
|
2
|
+
addAssets,
|
|
3
|
+
Emulator,
|
|
4
|
+
EmulatorAccount,
|
|
5
|
+
fromHex,
|
|
6
|
+
fromText,
|
|
7
|
+
generateEmulatorAccount,
|
|
8
|
+
Lucid,
|
|
9
|
+
} from '@lucid-evolution/lucid';
|
|
10
|
+
import { beforeEach, describe, test } from 'vitest';
|
|
11
|
+
import { LucidContext } from '../test-helpers';
|
|
12
|
+
import { treasuryCollect } from '../../src';
|
|
13
|
+
import {
|
|
14
|
+
EXAMPLE_TOKEN_1,
|
|
15
|
+
EXAMPLE_TOKEN_2,
|
|
16
|
+
EXAMPLE_TOKEN_3,
|
|
17
|
+
MAINNET_PROTOCOL_PARAMETERS,
|
|
18
|
+
} from '../indigo-test-helpers';
|
|
19
|
+
import { benchmarkAndAwaitTx } from '../utils/benchmark-utils';
|
|
20
|
+
import { findRandomTreasuryUtxoWithOnlyAda } from './treasury-queries';
|
|
21
|
+
import {
|
|
22
|
+
adaAssetClass,
|
|
23
|
+
AssetClass,
|
|
24
|
+
mkLovelacesOf,
|
|
25
|
+
} from '@3rd-eye-labs/cardano-offchain-common';
|
|
26
|
+
import { mkAssetsOf } from '@3rd-eye-labs/cardano-offchain-common';
|
|
27
|
+
import { expectScriptFailure } from '../utils/asserts';
|
|
28
|
+
import { treasuryMergeTx, treasurySplitTx } from './actions';
|
|
29
|
+
import { init } from '../endpoints/initialize';
|
|
30
|
+
import { iusdInitialAssetCfg } from '../mock/assets-mock';
|
|
31
|
+
|
|
32
|
+
type MyContext = LucidContext<{
|
|
33
|
+
admin: EmulatorAccount;
|
|
34
|
+
user: EmulatorAccount;
|
|
35
|
+
withdrawalAccount: EmulatorAccount;
|
|
36
|
+
}>;
|
|
37
|
+
|
|
38
|
+
const testAssetA: AssetClass = {
|
|
39
|
+
currencySymbol: fromHex(
|
|
40
|
+
// random generated
|
|
41
|
+
'cc072059ae741791b7b9c23d9baea6a0b0d764dec617ce7e027a8daa',
|
|
42
|
+
),
|
|
43
|
+
tokenName: fromHex(fromText('A')),
|
|
44
|
+
};
|
|
45
|
+
const testAssetB: AssetClass = {
|
|
46
|
+
currencySymbol: fromHex(
|
|
47
|
+
// random generated
|
|
48
|
+
'cc072059ae741791b7b9c23d9baea6a0b0d764dec617ce7e027a8dab',
|
|
49
|
+
),
|
|
50
|
+
tokenName: fromHex(fromText('B')),
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const testAssetC: AssetClass = {
|
|
54
|
+
currencySymbol: fromHex(
|
|
55
|
+
// random generated
|
|
56
|
+
'aa072059ae741791b7b9c23d9baea6a0b0d764dec617ce7e027a8dac',
|
|
57
|
+
),
|
|
58
|
+
tokenName: fromHex(fromText('C')),
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const testAssetD: AssetClass = {
|
|
62
|
+
currencySymbol: fromHex(
|
|
63
|
+
// random generated
|
|
64
|
+
'cc072059ae741791b7b9c23d9baea6a0b0d764dec617ce7e027a8dad',
|
|
65
|
+
),
|
|
66
|
+
tokenName: fromHex(fromText('D')),
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const testAssetE: AssetClass = {
|
|
70
|
+
currencySymbol: fromHex(
|
|
71
|
+
// random generated
|
|
72
|
+
'cc072059ae741791b7b9c23d9baea6a0b0d764dec617ce7e027a8dae',
|
|
73
|
+
),
|
|
74
|
+
tokenName: fromHex(fromText('E')),
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const testAssetF: AssetClass = {
|
|
78
|
+
currencySymbol: fromHex(
|
|
79
|
+
// random generated
|
|
80
|
+
'cc072059ae741791b7b9c23d9baea6a0b0d764dec617ce7e027a8daf',
|
|
81
|
+
),
|
|
82
|
+
tokenName: fromHex(fromText('F')),
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const testAssetG: AssetClass = {
|
|
86
|
+
currencySymbol: fromHex(
|
|
87
|
+
// random generated
|
|
88
|
+
'cc072059ae741791b7b9c23d9baea6a0b0d764dec617ce7e027a8dba',
|
|
89
|
+
),
|
|
90
|
+
tokenName: fromHex(fromText('G')),
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const testAssetH: AssetClass = {
|
|
94
|
+
currencySymbol: fromHex(
|
|
95
|
+
// random generated
|
|
96
|
+
'cc072059ae741791b7b9c23d9baea6a0b0d764dec617ce7e027a8dbb',
|
|
97
|
+
),
|
|
98
|
+
tokenName: fromHex(fromText('H')),
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const testAssetI: AssetClass = {
|
|
102
|
+
currencySymbol: fromHex(
|
|
103
|
+
// random generated
|
|
104
|
+
'cc072059ae741791b7b9c23d9baea6a0b0d764dec617ce7e027a8dbc',
|
|
105
|
+
),
|
|
106
|
+
tokenName: fromHex(fromText('I')),
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
const testAssetJ: AssetClass = {
|
|
110
|
+
currencySymbol: fromHex(
|
|
111
|
+
// random generated
|
|
112
|
+
'cc072059ae741791b7b9c23d9baea6a0b0d764dec617ce7e027a8dbd',
|
|
113
|
+
),
|
|
114
|
+
tokenName: fromHex(fromText('J')),
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const testAssetK: AssetClass = {
|
|
118
|
+
currencySymbol: fromHex(
|
|
119
|
+
// random generated
|
|
120
|
+
'cc072059ae741791b7b9c23d9baea6a0b0d764dec617ce7e027a8dbe',
|
|
121
|
+
),
|
|
122
|
+
tokenName: fromHex(fromText('K')),
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
// NOTE: Withdrawing and PrepareWithdrawal from Treasury is tested in gov.test.ts
|
|
126
|
+
describe('Treasury', () => {
|
|
127
|
+
beforeEach<MyContext>(async (context: MyContext) => {
|
|
128
|
+
context.users = {
|
|
129
|
+
admin: generateEmulatorAccount({
|
|
130
|
+
lovelace: BigInt(100_000_000_000_000),
|
|
131
|
+
}),
|
|
132
|
+
user: generateEmulatorAccount(
|
|
133
|
+
addAssets(
|
|
134
|
+
mkLovelacesOf(100_000_000_000_000n),
|
|
135
|
+
mkAssetsOf(EXAMPLE_TOKEN_1, 1_000_000_000_000_000n),
|
|
136
|
+
mkAssetsOf(EXAMPLE_TOKEN_2, 1_000_000_000_000_000n),
|
|
137
|
+
mkAssetsOf(EXAMPLE_TOKEN_3, 1_000_000_000_000_000n),
|
|
138
|
+
mkAssetsOf(testAssetA, 1_000_000_000_000_000n),
|
|
139
|
+
mkAssetsOf(testAssetB, 1_000_000_000_000_000n),
|
|
140
|
+
mkAssetsOf(testAssetC, 1_000_000_000_000_000n),
|
|
141
|
+
mkAssetsOf(testAssetD, 1_000_000_000_000_000n),
|
|
142
|
+
mkAssetsOf(testAssetE, 1_000_000_000_000_000n),
|
|
143
|
+
mkAssetsOf(testAssetF, 1_000_000_000_000_000n),
|
|
144
|
+
mkAssetsOf(testAssetG, 1_000_000_000_000_000n),
|
|
145
|
+
mkAssetsOf(testAssetH, 1_000_000_000_000_000n),
|
|
146
|
+
mkAssetsOf(testAssetI, 1_000_000_000_000_000n),
|
|
147
|
+
mkAssetsOf(testAssetJ, 1_000_000_000_000_000n),
|
|
148
|
+
mkAssetsOf(testAssetK, 1_000_000_000_000_000n),
|
|
149
|
+
),
|
|
150
|
+
),
|
|
151
|
+
withdrawalAccount: generateEmulatorAccount({}),
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
context.emulator = new Emulator(
|
|
155
|
+
[context.users.admin, context.users.user],
|
|
156
|
+
MAINNET_PROTOCOL_PARAMETERS,
|
|
157
|
+
);
|
|
158
|
+
context.lucid = await Lucid(context.emulator, 'Custom');
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
test<MyContext>('Merge (3 lovelace UTxOs)', async (context: MyContext) => {
|
|
162
|
+
context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
|
|
163
|
+
|
|
164
|
+
const [sysParams, __] = await init(
|
|
165
|
+
context.lucid,
|
|
166
|
+
[iusdInitialAssetCfg()],
|
|
167
|
+
context.emulator.slot,
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
await benchmarkAndAwaitTx(
|
|
171
|
+
'Treasury - Merge (3 lovelace UTxOs)',
|
|
172
|
+
await treasuryMergeTx(context, sysParams, [
|
|
173
|
+
mkLovelacesOf(50_000_000n),
|
|
174
|
+
mkLovelacesOf(50_000_000n),
|
|
175
|
+
mkLovelacesOf(50_000_000n),
|
|
176
|
+
]),
|
|
177
|
+
context.lucid,
|
|
178
|
+
context.emulator,
|
|
179
|
+
);
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
test<MyContext>('Merge (3 INDY UTxOs)', async (context: MyContext) => {
|
|
183
|
+
context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
|
|
184
|
+
|
|
185
|
+
const [sysParams, __] = await init(
|
|
186
|
+
context.lucid,
|
|
187
|
+
[iusdInitialAssetCfg()],
|
|
188
|
+
context.emulator.slot,
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
await benchmarkAndAwaitTx(
|
|
192
|
+
'Treasury - Merge (3 INDY UTxOs)',
|
|
193
|
+
await treasuryMergeTx(context, sysParams, [
|
|
194
|
+
addAssets(
|
|
195
|
+
mkLovelacesOf(5_000_000n),
|
|
196
|
+
mkAssetsOf(EXAMPLE_TOKEN_1, 1_000_000_000n),
|
|
197
|
+
),
|
|
198
|
+
addAssets(
|
|
199
|
+
mkLovelacesOf(5_000_000n),
|
|
200
|
+
mkAssetsOf(EXAMPLE_TOKEN_1, 1_000_000_000n),
|
|
201
|
+
),
|
|
202
|
+
addAssets(
|
|
203
|
+
mkLovelacesOf(5_000_000n),
|
|
204
|
+
mkAssetsOf(EXAMPLE_TOKEN_1, 1_000_000_000n),
|
|
205
|
+
),
|
|
206
|
+
]),
|
|
207
|
+
context.lucid,
|
|
208
|
+
context.emulator,
|
|
209
|
+
);
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
test<MyContext>('Merge (fail, 1 lovelace, 2 INDY UTxOs)', async (context: MyContext) => {
|
|
213
|
+
context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
|
|
214
|
+
|
|
215
|
+
const [sysParams, __] = await init(
|
|
216
|
+
context.lucid,
|
|
217
|
+
[iusdInitialAssetCfg()],
|
|
218
|
+
context.emulator.slot,
|
|
219
|
+
);
|
|
220
|
+
|
|
221
|
+
await expectScriptFailure(
|
|
222
|
+
'All inputs have to contain the same merging assets',
|
|
223
|
+
treasuryMergeTx(context, sysParams, [
|
|
224
|
+
mkLovelacesOf(5_000_000n),
|
|
225
|
+
addAssets(
|
|
226
|
+
mkLovelacesOf(5_000_000n),
|
|
227
|
+
mkAssetsOf(EXAMPLE_TOKEN_1, 1_000_000_000n),
|
|
228
|
+
),
|
|
229
|
+
addAssets(
|
|
230
|
+
mkLovelacesOf(5_000_000n),
|
|
231
|
+
mkAssetsOf(EXAMPLE_TOKEN_1, 1_000_000_000n),
|
|
232
|
+
),
|
|
233
|
+
]),
|
|
234
|
+
);
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
test<MyContext>('Split (12 assets)', async (context: MyContext) => {
|
|
238
|
+
context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
|
|
239
|
+
|
|
240
|
+
const [sysParams, __] = await init(
|
|
241
|
+
context.lucid,
|
|
242
|
+
[iusdInitialAssetCfg()],
|
|
243
|
+
context.emulator.slot,
|
|
244
|
+
);
|
|
245
|
+
|
|
246
|
+
await benchmarkAndAwaitTx(
|
|
247
|
+
'Treasury - Split (12 assets)',
|
|
248
|
+
await treasurySplitTx(
|
|
249
|
+
context,
|
|
250
|
+
sysParams,
|
|
251
|
+
addAssets(
|
|
252
|
+
mkLovelacesOf(5_000_000n),
|
|
253
|
+
mkAssetsOf(testAssetA, 1n),
|
|
254
|
+
mkAssetsOf(testAssetB, 1n),
|
|
255
|
+
mkAssetsOf(testAssetC, 1n),
|
|
256
|
+
mkAssetsOf(testAssetD, 1n),
|
|
257
|
+
mkAssetsOf(testAssetE, 1n),
|
|
258
|
+
mkAssetsOf(testAssetF, 1n),
|
|
259
|
+
mkAssetsOf(testAssetG, 1n),
|
|
260
|
+
mkAssetsOf(testAssetH, 1n),
|
|
261
|
+
mkAssetsOf(testAssetI, 1n),
|
|
262
|
+
mkAssetsOf(testAssetJ, 1n),
|
|
263
|
+
mkAssetsOf(testAssetK, 1n),
|
|
264
|
+
),
|
|
265
|
+
),
|
|
266
|
+
context.lucid,
|
|
267
|
+
context.emulator,
|
|
268
|
+
);
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
test<MyContext>('Split (fail, lovelace only)', async (context: MyContext) => {
|
|
272
|
+
context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
|
|
273
|
+
|
|
274
|
+
const [sysParams, __] = await init(
|
|
275
|
+
context.lucid,
|
|
276
|
+
[iusdInitialAssetCfg()],
|
|
277
|
+
context.emulator.slot,
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
await expectScriptFailure(
|
|
281
|
+
'All inputs must have more than 1 non-ADA asset or 1 non-ADA asset and more than 2x ADA buffer',
|
|
282
|
+
treasurySplitTx(context, sysParams, mkLovelacesOf(5_000_000n)),
|
|
283
|
+
);
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
test<MyContext>('Collect non-positive amount or negative extra lovelaces fails', async (context: MyContext) => {
|
|
287
|
+
context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
|
|
288
|
+
|
|
289
|
+
const [sysParams, __] = await init(
|
|
290
|
+
context.lucid,
|
|
291
|
+
[iusdInitialAssetCfg()],
|
|
292
|
+
context.emulator.slot,
|
|
293
|
+
);
|
|
294
|
+
|
|
295
|
+
const treasuryUTxO = await findRandomTreasuryUtxoWithOnlyAda(
|
|
296
|
+
context.lucid,
|
|
297
|
+
sysParams,
|
|
298
|
+
);
|
|
299
|
+
|
|
300
|
+
// This tests that the amount to collect cannot be negative.
|
|
301
|
+
await expectScriptFailure(
|
|
302
|
+
'Collected amount is positive',
|
|
303
|
+
treasuryCollect(
|
|
304
|
+
adaAssetClass,
|
|
305
|
+
-1_000_000n,
|
|
306
|
+
0n,
|
|
307
|
+
context.lucid,
|
|
308
|
+
sysParams,
|
|
309
|
+
treasuryUTxO,
|
|
310
|
+
treasuryUTxO,
|
|
311
|
+
),
|
|
312
|
+
);
|
|
313
|
+
|
|
314
|
+
// This tests that the amount to collect cannot be zero.
|
|
315
|
+
await expectScriptFailure(
|
|
316
|
+
'Collected amount is positive',
|
|
317
|
+
treasuryCollect(
|
|
318
|
+
adaAssetClass,
|
|
319
|
+
0n,
|
|
320
|
+
0n,
|
|
321
|
+
context.lucid,
|
|
322
|
+
sysParams,
|
|
323
|
+
treasuryUTxO,
|
|
324
|
+
treasuryUTxO,
|
|
325
|
+
),
|
|
326
|
+
);
|
|
327
|
+
|
|
328
|
+
// This tests that the extra lovelaces cannot be negative.
|
|
329
|
+
await expectScriptFailure(
|
|
330
|
+
'Collected amount is positive',
|
|
331
|
+
treasuryCollect(
|
|
332
|
+
adaAssetClass,
|
|
333
|
+
1n,
|
|
334
|
+
-1_000_000n,
|
|
335
|
+
context.lucid,
|
|
336
|
+
sysParams,
|
|
337
|
+
treasuryUTxO,
|
|
338
|
+
treasuryUTxO,
|
|
339
|
+
),
|
|
340
|
+
);
|
|
341
|
+
});
|
|
342
|
+
});
|