@indigo-labs/indigo-sdk
Version:
Indigo SDK for interacting with Indigo endpoints via lucid-evolution
345 lines (309 loc) • 9.76 kB
text/typescript
import {
addAssets,
Emulator,
EmulatorAccount,
fromHex,
fromText,
generateEmulatorAccount,
Lucid,
} from '@lucid-evolution/lucid';
import { beforeEach, describe, test } from 'vitest';
import { LucidContext } from '../test-helpers';
import { treasuryCollect } from '../../src';
import {
EXAMPLE_TOKEN_1,
EXAMPLE_TOKEN_2,
EXAMPLE_TOKEN_3,
MAINNET_PROTOCOL_PARAMETERS,
} from '../indigo-test-helpers';
import { benchmarkAndAwaitTx } from '../utils/benchmark-utils';
import { findRandomTreasuryUtxoWithOnlyAda } from './treasury-queries';
import {
adaAssetClass,
AssetClass,
mkLovelacesOf,
} from '@3rd-eye-labs/cardano-offchain-common';
import { mkAssetsOf } from '@3rd-eye-labs/cardano-offchain-common';
import { expectScriptFailure } from '../utils/asserts';
import { treasuryMergeTx, treasurySplitTx } from './actions';
import { init } from '../endpoints/initialize';
import { iusdInitialAssetCfg } from '../mock/assets-mock';
type MyContext = LucidContext<{
admin: EmulatorAccount;
user: EmulatorAccount;
withdrawalAccount: EmulatorAccount;
}>;
const testAssetA: AssetClass = {
currencySymbol: fromHex(
// random generated
'cc072059ae741791b7b9c23d9baea6a0b0d764dec617ce7e027a8daa',
),
tokenName: fromHex(fromText('A')),
};
const testAssetB: AssetClass = {
currencySymbol: fromHex(
// random generated
'cc072059ae741791b7b9c23d9baea6a0b0d764dec617ce7e027a8dab',
),
tokenName: fromHex(fromText('B')),
};
const testAssetC: AssetClass = {
currencySymbol: fromHex(
// random generated
'aa072059ae741791b7b9c23d9baea6a0b0d764dec617ce7e027a8dac',
),
tokenName: fromHex(fromText('C')),
};
const testAssetD: AssetClass = {
currencySymbol: fromHex(
// random generated
'cc072059ae741791b7b9c23d9baea6a0b0d764dec617ce7e027a8dad',
),
tokenName: fromHex(fromText('D')),
};
const testAssetE: AssetClass = {
currencySymbol: fromHex(
// random generated
'cc072059ae741791b7b9c23d9baea6a0b0d764dec617ce7e027a8dae',
),
tokenName: fromHex(fromText('E')),
};
const testAssetF: AssetClass = {
currencySymbol: fromHex(
// random generated
'cc072059ae741791b7b9c23d9baea6a0b0d764dec617ce7e027a8daf',
),
tokenName: fromHex(fromText('F')),
};
const testAssetG: AssetClass = {
currencySymbol: fromHex(
// random generated
'cc072059ae741791b7b9c23d9baea6a0b0d764dec617ce7e027a8dba',
),
tokenName: fromHex(fromText('G')),
};
const testAssetH: AssetClass = {
currencySymbol: fromHex(
// random generated
'cc072059ae741791b7b9c23d9baea6a0b0d764dec617ce7e027a8dbb',
),
tokenName: fromHex(fromText('H')),
};
const testAssetI: AssetClass = {
currencySymbol: fromHex(
// random generated
'cc072059ae741791b7b9c23d9baea6a0b0d764dec617ce7e027a8dbc',
),
tokenName: fromHex(fromText('I')),
};
const testAssetJ: AssetClass = {
currencySymbol: fromHex(
// random generated
'cc072059ae741791b7b9c23d9baea6a0b0d764dec617ce7e027a8dbd',
),
tokenName: fromHex(fromText('J')),
};
const testAssetK: AssetClass = {
currencySymbol: fromHex(
// random generated
'cc072059ae741791b7b9c23d9baea6a0b0d764dec617ce7e027a8dbe',
),
tokenName: fromHex(fromText('K')),
};
// NOTE: Withdrawing and PrepareWithdrawal from Treasury is tested in gov.test.ts
describe('Treasury', () => {
beforeEach<MyContext>(async (context: MyContext) => {
context.users = {
admin: generateEmulatorAccount({
lovelace: BigInt(100_000_000_000_000),
}),
user: generateEmulatorAccount(
addAssets(
mkLovelacesOf(100_000_000_000_000n),
mkAssetsOf(EXAMPLE_TOKEN_1, 1_000_000_000_000_000n),
mkAssetsOf(EXAMPLE_TOKEN_2, 1_000_000_000_000_000n),
mkAssetsOf(EXAMPLE_TOKEN_3, 1_000_000_000_000_000n),
mkAssetsOf(testAssetA, 1_000_000_000_000_000n),
mkAssetsOf(testAssetB, 1_000_000_000_000_000n),
mkAssetsOf(testAssetC, 1_000_000_000_000_000n),
mkAssetsOf(testAssetD, 1_000_000_000_000_000n),
mkAssetsOf(testAssetE, 1_000_000_000_000_000n),
mkAssetsOf(testAssetF, 1_000_000_000_000_000n),
mkAssetsOf(testAssetG, 1_000_000_000_000_000n),
mkAssetsOf(testAssetH, 1_000_000_000_000_000n),
mkAssetsOf(testAssetI, 1_000_000_000_000_000n),
mkAssetsOf(testAssetJ, 1_000_000_000_000_000n),
mkAssetsOf(testAssetK, 1_000_000_000_000_000n),
),
),
withdrawalAccount: generateEmulatorAccount({}),
};
context.emulator = new Emulator(
[],
MAINNET_PROTOCOL_PARAMETERS,
);
context.lucid = await Lucid(context.emulator, 'Custom');
context.lucid.selectWallet.fromSeed(context.users.admin.seedPhrase);
});
test<MyContext>('Merge (3 lovelace UTxOs)', async (context: MyContext) => {
const [sysParams, __] = await init(
context.lucid,
[],
context.emulator.slot,
);
context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
await benchmarkAndAwaitTx(
'Treasury - Merge (3 lovelace UTxOs)',
await treasuryMergeTx(context, sysParams, [
mkLovelacesOf(50_000_000n),
mkLovelacesOf(50_000_000n),
mkLovelacesOf(50_000_000n),
]),
context.lucid,
context.emulator,
);
});
test<MyContext>('Merge (3 INDY UTxOs)', async (context: MyContext) => {
const [sysParams, __] = await init(
context.lucid,
[],
context.emulator.slot,
);
context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
await benchmarkAndAwaitTx(
'Treasury - Merge (3 INDY UTxOs)',
await treasuryMergeTx(context, sysParams, [
addAssets(
mkLovelacesOf(5_000_000n),
mkAssetsOf(EXAMPLE_TOKEN_1, 1_000_000_000n),
),
addAssets(
mkLovelacesOf(5_000_000n),
mkAssetsOf(EXAMPLE_TOKEN_1, 1_000_000_000n),
),
addAssets(
mkLovelacesOf(5_000_000n),
mkAssetsOf(EXAMPLE_TOKEN_1, 1_000_000_000n),
),
]),
context.lucid,
context.emulator,
);
});
test<MyContext>('Merge (fail, 1 lovelace, 2 INDY UTxOs)', async (context: MyContext) => {
const [sysParams, __] = await init(
context.lucid,
[],
context.emulator.slot,
);
context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
await expectScriptFailure(
'All inputs have to contain the same merging assets',
treasuryMergeTx(context, sysParams, [
mkLovelacesOf(5_000_000n),
addAssets(
mkLovelacesOf(5_000_000n),
mkAssetsOf(EXAMPLE_TOKEN_1, 1_000_000_000n),
),
addAssets(
mkLovelacesOf(5_000_000n),
mkAssetsOf(EXAMPLE_TOKEN_1, 1_000_000_000n),
),
]),
);
});
test<MyContext>('Split (12 assets)', async (context: MyContext) => {
const [sysParams, __] = await init(
context.lucid,
[],
context.emulator.slot,
);
context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
await benchmarkAndAwaitTx(
'Treasury - Split (12 assets)',
await treasurySplitTx(
context,
sysParams,
addAssets(
mkLovelacesOf(5_000_000n),
mkAssetsOf(testAssetA, 1n),
mkAssetsOf(testAssetB, 1n),
mkAssetsOf(testAssetC, 1n),
mkAssetsOf(testAssetD, 1n),
mkAssetsOf(testAssetE, 1n),
mkAssetsOf(testAssetF, 1n),
mkAssetsOf(testAssetG, 1n),
mkAssetsOf(testAssetH, 1n),
mkAssetsOf(testAssetI, 1n),
mkAssetsOf(testAssetJ, 1n),
mkAssetsOf(testAssetK, 1n),
),
),
context.lucid,
context.emulator,
);
});
test<MyContext>('Split (fail, lovelace only)', async (context: MyContext) => {
const [sysParams, __] = await init(
context.lucid,
[],
context.emulator.slot,
);
context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
await expectScriptFailure(
'All inputs must have more than 1 non-ADA asset or 1 non-ADA asset and more than 2x ADA buffer',
treasurySplitTx(context, sysParams, mkLovelacesOf(5_000_000n)),
);
});
test<MyContext>('Collect non-positive amount or negative extra lovelaces fails', async (context: MyContext) => {
const [sysParams, __] = await init(
context.lucid,
[],
context.emulator.slot,
);
context.lucid.selectWallet.fromSeed(context.users.user.seedPhrase);
const treasuryUTxO = await findRandomTreasuryUtxoWithOnlyAda(
context.lucid,
sysParams,
);
// This tests that the amount to collect cannot be negative.
await expectScriptFailure(
'Collected amount is positive',
treasuryCollect(
adaAssetClass,
-1_000_000n,
0n,
context.lucid,
sysParams,
treasuryUTxO,
treasuryUTxO,
),
);
// This tests that the amount to collect cannot be zero.
await expectScriptFailure(
'Collected amount is positive',
treasuryCollect(
adaAssetClass,
0n,
0n,
context.lucid,
sysParams,
treasuryUTxO,
treasuryUTxO,
),
);
// This tests that the extra lovelaces cannot be negative.
await expectScriptFailure(
'Collected amount is positive',
treasuryCollect(
adaAssetClass,
1n,
-1_000_000n,
context.lucid,
sysParams,
treasuryUTxO,
treasuryUTxO,
),
);
});
});